mirror of
https://github.com/hansjone/oclaw.git
synced 2026-10-13 02:20:45 +08:00
Enable default emergency account
This commit is contained in:
parent
70bde46eff
commit
07cfbefb6c
9 changed files with 43 additions and 31 deletions
|
|
@ -33,7 +33,7 @@ window.__ModuleLoader__.load({
|
|||
"ui.settingsTitle": "UAC 认证",
|
||||
"ui.settingsIntro": "工号+token 双校验;UAC 挂死时用应急账号 administrator 密码登录。",
|
||||
"ui.loginRequiredPage": "请先登录后查看此页",
|
||||
"ui.roleHint": "当前角色:{role}。超管只是身份标签,与管理员权限相同;显式配置的初始管理员在首次登录时获得超管身份,也可在「用户管理」设为管理员。应急账号 administrator 需先设密码,再在登录面板用账密登录。",
|
||||
"ui.roleHint": "当前角色:{role}。超管只是身份标签,与管理员权限相同;显式配置的初始管理员在首次登录时获得超管身份,也可在「用户管理」设为管理员。应急账号默认账号 administrator、密码 Admin@123,首次登录后请修改。",
|
||||
"ui.deployConfig": "部署配置",
|
||||
"ui.userSearchUrl": "用户搜索 URL(token 校验)",
|
||||
"ui.workspaceRoot": "工作区根目录(空=$DSH_HOME/user-workspaces)",
|
||||
|
|
@ -78,8 +78,8 @@ window.__ModuleLoader__.load({
|
|||
"ui.refreshQr": "刷新二维码",
|
||||
"ui.fallbackLink": "UAC 不可用?应急账号登录",
|
||||
"ui.fallbackDisabledLink": "应急登录(未启用)",
|
||||
"ui.fallbackDisabledHint": "应急密码未配置或已停用。请用已登录的管理员在「账户 / 权限」中设置新的独立强密码后重试。旧共享默认密码不可用。",
|
||||
"ui.fallbackDisabledDetail": "当前未启用应急密码。用已授权管理员登录后,在设置中配置新密码即可恢复此入口。",
|
||||
"ui.fallbackDisabledHint": "应急账号已关闭。请用已登录的管理员在「账户 / 权限」中重新设置并启用。",
|
||||
"ui.fallbackDisabledDetail": "当前未启用应急账号。用已授权管理员登录后,在设置中重新设置密码即可恢复此入口。",
|
||||
"ui.fallbackLogin": "应急登录",
|
||||
"ui.fallbackDetail": "UAC / 扫码不可用时使用",
|
||||
"ui.localKeyLink": "本机密钥解锁",
|
||||
|
|
@ -180,7 +180,7 @@ window.__ModuleLoader__.load({
|
|||
"ui.settingsTitle": "UAC Auth",
|
||||
"ui.settingsIntro": "EmpNo + token verification; when UAC is down, sign in with emergency account administrator.",
|
||||
"ui.loginRequiredPage": "Sign in to view this page",
|
||||
"ui.roleHint": "Current role: {role}. Super admin is only an identity label with the same permissions as admin; the explicitly configured initial administrator receives that identity on first login, or grant admin in User management. Set the emergency password before using administrator on the login panel.",
|
||||
"ui.roleHint": "Current role: {role}. Super admin is only an identity label with the same permissions as admin; the explicitly configured initial administrator receives that identity on first login, or grant admin in User management. The emergency account defaults to administrator / Admin@123; change it after first sign-in.",
|
||||
"ui.deployConfig": "Deploy config",
|
||||
"ui.userSearchUrl": "User search URL (token verify)",
|
||||
"ui.workspaceRoot": "Workspace root (empty=$DSH_HOME/user-workspaces)",
|
||||
|
|
@ -225,8 +225,8 @@ window.__ModuleLoader__.load({
|
|||
"ui.refreshQr": "Refresh QR",
|
||||
"ui.fallbackLink": "UAC down? Emergency account",
|
||||
"ui.fallbackDisabledLink": "Emergency login (disabled)",
|
||||
"ui.fallbackDisabledHint": "Emergency password is not configured or was disabled. Ask a signed-in admin to set a new strong password under Account / Permissions. The old shared default password cannot be used.",
|
||||
"ui.fallbackDisabledDetail": "Emergency password is off. After an authorized admin sets a new password in settings, this entry works again.",
|
||||
"ui.fallbackDisabledHint": "The emergency account is disabled. Ask a signed-in admin to set a new password and enable it under Account / Permissions.",
|
||||
"ui.fallbackDisabledDetail": "The emergency account is off. An authorized admin can set its password again in settings to restore this entry.",
|
||||
"ui.fallbackLogin": "Emergency login",
|
||||
"ui.fallbackDetail": "Use when UAC / QR is unavailable",
|
||||
"ui.localKeyLink": "Unlock with local key",
|
||||
|
|
|
|||
|
|
@ -26,7 +26,7 @@ export const MESSAGES = {
|
|||
'ui.settingsTitle': 'UAC 认证',
|
||||
'ui.settingsIntro': '工号+token 双校验;UAC 挂死时用应急账号 administrator 密码登录。',
|
||||
'ui.loginRequiredPage': '请先登录后查看此页',
|
||||
'ui.roleHint': '当前角色:{role}。超管只是身份标签,与管理员权限相同;显式配置的初始管理员在首次登录时获得超管身份,也可在「用户管理」设为管理员。应急账号 administrator 需先设密码,再在登录面板用账密登录。',
|
||||
'ui.roleHint': '当前角色:{role}。超管只是身份标签,与管理员权限相同;显式配置的初始管理员在首次登录时获得超管身份,也可在「用户管理」设为管理员。应急账号默认账号 administrator、密码 Admin@123,首次登录后请修改。',
|
||||
'ui.deployConfig': '部署配置',
|
||||
'ui.userSearchUrl': '用户搜索 URL(token 校验)',
|
||||
'ui.workspaceRoot': '工作区根目录(空=$DSH_HOME/user-workspaces)',
|
||||
|
|
@ -213,7 +213,7 @@ export const MESSAGES = {
|
|||
'ui.settingsTitle': 'UAC Auth',
|
||||
'ui.settingsIntro': 'EmpNo + token verification; when UAC is down, sign in with emergency account administrator.',
|
||||
'ui.loginRequiredPage': 'Sign in to view this page',
|
||||
'ui.roleHint': 'Current role: {role}. Super admin is only an identity label with the same permissions as admin; the explicitly configured initial administrator receives that identity on first login, or grant admin in User management. Set the emergency password before using administrator on the login panel.',
|
||||
'ui.roleHint': 'Current role: {role}. Super admin is only an identity label with the same permissions as admin; the explicitly configured initial administrator receives that identity on first login, or grant admin in User management. The emergency account defaults to administrator / Admin@123; change it after first sign-in.',
|
||||
'ui.deployConfig': 'Deploy config',
|
||||
'ui.userSearchUrl': 'User search URL (token verify)',
|
||||
'ui.workspaceRoot': 'Workspace root (empty=$DSH_HOME/user-workspaces)',
|
||||
|
|
|
|||
|
|
@ -29,7 +29,7 @@ const ACCOUNT_STATUS = {
|
|||
DISABLED: 'disabled',
|
||||
}
|
||||
|
||||
/** Known shared default from pre-0.3 installs — must never remain usable (R10). */
|
||||
/** Shared emergency default requested for first boot and legacy migrations. */
|
||||
const LEGACY_DEFAULT_SHA256 = createHash('sha256').update('Admin@123').digest('hex')
|
||||
|
||||
/**
|
||||
|
|
@ -141,7 +141,7 @@ export function canToggleViewAllSessions(role) {
|
|||
return isAdminClass(role)
|
||||
}
|
||||
|
||||
/** Historical default — never enable automatically (R10). */
|
||||
/** Default emergency credentials. Rotate the password after first sign-in. */
|
||||
export const DEFAULT_FALLBACK_PASSWORD = 'Admin@123'
|
||||
export const DEFAULT_FALLBACK_USERNAME = 'administrator'
|
||||
|
||||
|
|
@ -149,7 +149,7 @@ export const DEFAULT_FALLBACK_USERNAME = 'administrator'
|
|||
* RolesStore — 角色存储
|
||||
* 内存 Map + 可选 JSON 文件持久化
|
||||
*
|
||||
* fallback admin: 默认关闭;须在设置中显式设置 scrypt 口令(≥10,禁 Admin@123)。
|
||||
* fallback admin: first boot uses the shared Admin@123 password; admins can rotate or disable it.
|
||||
* 登录路径: POST /uds-auth/api/fallback/login { username, password }
|
||||
*/
|
||||
export class RolesStore {
|
||||
|
|
@ -170,18 +170,21 @@ export class RolesStore {
|
|||
this._saveTimer = null
|
||||
}
|
||||
|
||||
/**
|
||||
* New installs do NOT enable a shared default password (SEC-08).
|
||||
* Admins must set a password explicitly via settings / setFallbackPassword.
|
||||
*/
|
||||
/** Seed the requested default emergency password on first initialization. */
|
||||
_ensureDefaultFallback() {
|
||||
// no-op — kept for call-site compatibility
|
||||
if (this._fallbackPasswordHash !== null) return false
|
||||
this._fallbackPasswordHash = hashPasswordScrypt(DEFAULT_FALLBACK_PASSWORD)
|
||||
this._fallbackNeedsRehash = false
|
||||
this._fallbackCredVersion = Math.max(1, this._fallbackCredVersion + 1)
|
||||
this._dirty = true
|
||||
return true
|
||||
}
|
||||
|
||||
// === 持久化 ===
|
||||
|
||||
async init() {
|
||||
let loadedOk = false
|
||||
let seedDefaultFallback = !this._rolesFile
|
||||
if (this._rolesFile) {
|
||||
try {
|
||||
const raw = await readFile(this._rolesFile, 'utf-8')
|
||||
|
|
@ -196,6 +199,9 @@ export class RolesStore {
|
|||
}
|
||||
if (Object.prototype.hasOwnProperty.call(data, 'fallbackPasswordHash')) {
|
||||
this._fallbackPasswordHash = data.fallbackPasswordHash || null
|
||||
} else {
|
||||
// Upgrade older roles files that predate explicit fallback state.
|
||||
seedDefaultFallback = true
|
||||
}
|
||||
this._fallbackCredVersion = Number.isSafeInteger(data.fallbackCredVersion)
|
||||
&& data.fallbackCredVersion >= 0 ? data.fallbackCredVersion : 0
|
||||
|
|
@ -207,9 +213,10 @@ export class RolesStore {
|
|||
loadedOk = true
|
||||
} catch (err) {
|
||||
if (err.code === 'ENOENT') {
|
||||
// First boot — empty roles, fallback disabled until explicitly configured.
|
||||
// First boot — seed and persist the requested default credentials.
|
||||
seedDefaultFallback = true
|
||||
console.info(
|
||||
'[uds-auth] roles file missing; fallback password disabled until configured'
|
||||
'[uds-auth] roles file missing; enabling default emergency account administrator'
|
||||
+ ` (set initialAdmin via UDS_AUTH_INITIAL_ADMIN)`,
|
||||
)
|
||||
} else {
|
||||
|
|
@ -219,11 +226,12 @@ export class RolesStore {
|
|||
}
|
||||
}
|
||||
}
|
||||
// R10: known shared default hash cannot remain enabled after upgrade.
|
||||
// Upgrade the historical SHA-256 default to a salted scrypt hash.
|
||||
if (loadedOk && this._fallbackPasswordHash
|
||||
&& String(this._fallbackPasswordHash).toLowerCase() === LEGACY_DEFAULT_SHA256) {
|
||||
console.warn('[uds-auth] refusing legacy shared default fallback password — disabled until reset')
|
||||
this._fallbackPasswordHash = null
|
||||
console.warn('[uds-auth] migrating legacy default fallback password to scrypt')
|
||||
this._fallbackPasswordHash = hashPasswordScrypt(DEFAULT_FALLBACK_PASSWORD)
|
||||
this._fallbackCredVersion = Math.max(1, this._fallbackCredVersion + 1)
|
||||
this._dirty = true
|
||||
await this._save()
|
||||
} else if (loadedOk && this._fallbackPasswordHash
|
||||
|
|
@ -231,6 +239,10 @@ export class RolesStore {
|
|||
this._fallbackNeedsRehash = true
|
||||
console.warn('[uds-auth] legacy SHA-256 fallback hash loaded — will upgrade on next successful login')
|
||||
}
|
||||
if (seedDefaultFallback && !this._loadFailed) {
|
||||
this._ensureDefaultFallback()
|
||||
await this.flush()
|
||||
}
|
||||
if (loadedOk && this._fallbackPasswordHash) {
|
||||
console.info('[uds-auth] fallback_admin password loaded from roles file')
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue