Skip to content

Commit 178077e

Browse files
committed
Use init flow by default for admin auth
1 parent c0ab12a commit 178077e

3 files changed

Lines changed: 19 additions & 9 deletions

File tree

.env.example

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,11 @@
1-
ADMIN_PASSWORD=Sheng123..
2-
SESSION_SECRET=change-this-session-secret-after-deploy
1+
# Optional: set this only if you want to force a fixed admin password from environment.
2+
# If omitted, open the site for the first time and initialize the admin password in the UI.
3+
# ADMIN_PASSWORD=
4+
5+
# Optional: set this only if you need a fixed session secret.
6+
# If omitted, the app generates one automatically and stores it under data/config/admin-auth.json.
7+
# SESSION_SECRET=
8+
39
NODE_ENV=production
410
PORT=3000
511
DATA_DIR=/app/data

docker-compose.release.yml

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,8 +7,6 @@ services:
77
environment:
88
NODE_ENV: ${NODE_ENV:-production}
99
PORT: 3000
10-
ADMIN_PASSWORD: ${ADMIN_PASSWORD:-Sheng123..}
11-
SESSION_SECRET: ${SESSION_SECRET:-change-this-session-secret-after-deploy}
1210
DATA_DIR: ${DATA_DIR:-/app/data}
1311
volumes:
1412
- ./data:${DATA_DIR:-/app/data}

src/lib/local-admin/auth.ts

Lines changed: 11 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,13 @@
1-
import { createHash, timingSafeEqual } from 'crypto'
1+
import { createHash, randomBytes, timingSafeEqual } from 'crypto'
22
import { readConfigJson, writeConfigJson } from './storage'
33

44
const SESSION_COOKIE = 'blog_admin_session'
5-
const DEFAULT_SESSION_SECRET = 'blog-local-secret-change-me'
65
const ADMIN_CONFIG_FILE = 'admin-auth.json'
76

87
type AdminAuthConfig = {
98
passwordHash?: string
109
initializedAt?: string
10+
sessionSecret?: string
1111
}
1212

1313
function sha256(input: string) {
@@ -37,8 +37,13 @@ export async function initializeAdminPassword(password: string) {
3737
return next
3838
}
3939

40-
export function getSessionSecret() {
41-
return process.env.SESSION_SECRET || DEFAULT_SESSION_SECRET
40+
export async function getSessionSecret() {
41+
if (process.env.SESSION_SECRET) return process.env.SESSION_SECRET
42+
const config = await getAdminAuthConfig()
43+
if (config.sessionSecret) return config.sessionSecret
44+
const sessionSecret = randomBytes(32).toString('hex')
45+
await writeConfigJson(ADMIN_CONFIG_FILE, { ...config, sessionSecret })
46+
return sessionSecret
4247
}
4348

4449
export function getSessionCookieName() {
@@ -61,9 +66,10 @@ export async function verifyAdminPassword(password: string) {
6166

6267
export async function createSessionToken() {
6368
const passwordHash = (await getStoredAdminPasswordHash()) || 'uninitialized'
64-
return sha256(`${getSessionSecret()}:${passwordHash}`)
69+
return sha256(`${await getSessionSecret()}:${passwordHash}`)
6570
}
6671

72+
6773
export async function verifySessionToken(token?: string | null) {
6874
if (!token) return false
6975
const expectedToken = await createSessionToken()

0 commit comments

Comments
 (0)