fix(auth): update PocketBase v0.23+ auth endpoint and rename users collection
- Replace deprecated /api/admins/auth-with-password with /api/collections/_superusers/auth-with-password in both the SvelteKit UI (pocketbase.ts) and Go scraper (pocketbase.go) - Rename custom users collection to app_users to avoid name clash with PocketBase's built-in users auth collection - Fix docker-compose volume mount path pb/pb_data -> pb_data so persisted data matches the entrypoint --dir flag - Add PB_ADMIN_EMAIL/PB_ADMIN_PASSWORD env vars to pocketbase service so the superuser is auto-created on first boot
This commit is contained in:
@@ -45,10 +45,14 @@ services:
|
|||||||
image: ghcr.io/muchobien/pocketbase:latest
|
image: ghcr.io/muchobien/pocketbase:latest
|
||||||
#container_name: libnovel-pocketbase
|
#container_name: libnovel-pocketbase
|
||||||
restart: unless-stopped
|
restart: unless-stopped
|
||||||
|
environment:
|
||||||
|
# Auto-create superuser on first boot (used by entrypoint.sh)
|
||||||
|
PB_ADMIN_EMAIL: "${POCKETBASE_ADMIN_EMAIL:-admin@libnovel.local}"
|
||||||
|
PB_ADMIN_PASSWORD: "${POCKETBASE_ADMIN_PASSWORD:-changeme123}"
|
||||||
ports:
|
ports:
|
||||||
- "${POCKETBASE_PORT:-8090}:8090"
|
- "${POCKETBASE_PORT:-8090}:8090"
|
||||||
volumes:
|
volumes:
|
||||||
- pb_data:/pb/pb_data
|
- pb_data:/pb_data
|
||||||
healthcheck:
|
healthcheck:
|
||||||
test: ["CMD", "wget", "-qO-", "http://localhost:8090/api/health"]
|
test: ["CMD", "wget", "-qO-", "http://localhost:8090/api/health"]
|
||||||
interval: 10s
|
interval: 10s
|
||||||
|
|||||||
@@ -9,7 +9,7 @@
|
|||||||
// ranking_html — page(number,unique), html(text), updated(date)
|
// ranking_html — page(number,unique), html(text), updated(date)
|
||||||
// progress — session_id(text), slug(text), chapter(number), updated(date)
|
// progress — session_id(text), slug(text), chapter(number), updated(date)
|
||||||
// audio_cache — cache_key(text,unique), filename(text), updated(date)
|
// audio_cache — cache_key(text,unique), filename(text), updated(date)
|
||||||
// users — username(text,unique), password_hash(text), role(text), created(date)
|
// app_users — username(text,unique), password_hash(text), role(text), created(date)
|
||||||
package storage
|
package storage
|
||||||
|
|
||||||
import (
|
import (
|
||||||
@@ -60,7 +60,7 @@ func (p *pbClient) authenticate(ctx context.Context) error {
|
|||||||
"password": p.cfg.AdminPassword,
|
"password": p.cfg.AdminPassword,
|
||||||
})
|
})
|
||||||
req, err := http.NewRequestWithContext(ctx, http.MethodPost,
|
req, err := http.NewRequestWithContext(ctx, http.MethodPost,
|
||||||
p.cfg.BaseURL+"/api/admins/auth-with-password", bytes.NewReader(body))
|
p.cfg.BaseURL+"/api/collections/_superusers/auth-with-password", bytes.NewReader(body))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
@@ -314,7 +314,7 @@ func (s *PocketBaseStore) EnsureCollections(ctx context.Context) error {
|
|||||||
},
|
},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "users",
|
"name": "app_users",
|
||||||
"type": "base",
|
"type": "base",
|
||||||
"schema": []map[string]interface{}{
|
"schema": []map[string]interface{}{
|
||||||
{"name": "username", "type": "text", "required": true, "options": map[string]interface{}{"min": 3, "max": 32}},
|
{"name": "username", "type": "text", "required": true, "options": map[string]interface{}{"min": 3, "max": 32}},
|
||||||
|
|||||||
@@ -61,7 +61,7 @@ async function getToken(): Promise<string> {
|
|||||||
|
|
||||||
log.debug('pocketbase', 'authenticating with admin credentials', { url: PB_URL, email: PB_EMAIL });
|
log.debug('pocketbase', 'authenticating with admin credentials', { url: PB_URL, email: PB_EMAIL });
|
||||||
|
|
||||||
const res = await fetch(`${PB_URL}/api/admins/auth-with-password`, {
|
const res = await fetch(`${PB_URL}/api/collections/_superusers/auth-with-password`, {
|
||||||
method: 'POST',
|
method: 'POST',
|
||||||
headers: { 'Content-Type': 'application/json' },
|
headers: { 'Content-Type': 'application/json' },
|
||||||
body: JSON.stringify({ identity: PB_EMAIL, password: PB_PASSWORD })
|
body: JSON.stringify({ identity: PB_EMAIL, password: PB_PASSWORD })
|
||||||
@@ -213,7 +213,7 @@ function verifyPassword(password: string, stored: string): boolean {
|
|||||||
* Look up a user by username. Returns null if not found.
|
* Look up a user by username. Returns null if not found.
|
||||||
*/
|
*/
|
||||||
export async function getUserByUsername(username: string): Promise<User | null> {
|
export async function getUserByUsername(username: string): Promise<User | null> {
|
||||||
return listOne<User>('users', `username="${username.replace(/"/g, '\\"')}"`);
|
return listOne<User>('app_users', `username="${username.replace(/"/g, '\\"')}"`);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -228,7 +228,7 @@ export async function createUser(username: string, password: string, role = 'use
|
|||||||
}
|
}
|
||||||
const password_hash = hashPassword(password);
|
const password_hash = hashPassword(password);
|
||||||
log.info('pocketbase', 'createUser: inserting new user', { username, role });
|
log.info('pocketbase', 'createUser: inserting new user', { username, role });
|
||||||
const res = await pbPost('/api/collections/users/records', {
|
const res = await pbPost('/api/collections/app_users/records', {
|
||||||
username,
|
username,
|
||||||
password_hash,
|
password_hash,
|
||||||
role,
|
role,
|
||||||
|
|||||||
Reference in New Issue
Block a user