forked from dsh/panel-auth
refactor: move logout/change-password UI from floating widget to settings
The injected floating buttons overlapped the mobile composer send button. Replace the tapIndex-injected widget with a proper client plugin (panel-auth-ui, ui/ package): registers an account & security section in the panel settings via the settings.section slot, with change-password form and logout action. Host plugin keeps only the /panel-auth/change- password and /panel-auth/logout endpoints. - ui/: ModuleLoader-format client bundle (dsh.client declaration, exports ./client and ./package.json), host no-op stub, bare-package symlink required in the profile node_modules (documented in README). - Host: renderAuthWidget/injectWidget/tapIndex injection removed. - Tests: widget tests removed; change-password flows unchanged.
This commit is contained in:
@@ -6,7 +6,7 @@ import { strict as assert } from 'node:assert'
|
||||
import { mkdtempSync, readFileSync, rmSync } from 'node:fs'
|
||||
import { tmpdir } from 'node:os'
|
||||
import { join } from 'node:path'
|
||||
import { createGuard, installGuard, createAuditWriter, createLockout, renderLoginPage, renderAuthWidget, injectWidget } from './index.js'
|
||||
import { createGuard, installGuard, createAuditWriter, createLockout, renderLoginPage } from './index.js'
|
||||
import { hashPassword, verifyPassword } from './crypto.js'
|
||||
|
||||
const tmp = mkdtempSync(join(tmpdir(), 'panel-auth-test-'))
|
||||
@@ -274,14 +274,6 @@ assert.ok(auditLines.some((e) => e.event === 'password-change'), 'audit missing
|
||||
assert.ok(auditLines.some((e) => e.event === 'login-fail' && e.reason === 'password-change-old-mismatch'), 'audit missing old-mismatch entry')
|
||||
assert.equal(auditLines.every((e) => typeof e.ip === 'string' && typeof e.ts === 'string'), true)
|
||||
|
||||
// 11b. widget rendering and index injection
|
||||
const widget = renderAuthWidget({ logoutPath: '/panel-auth/logout', changePasswordPath: '/panel-auth/change-password' })
|
||||
assert.ok(widget.includes('id="pna-widget"') && widget.includes('id="pna-logout"') && widget.includes('id="pna-change"') && widget.includes('pna-modal'))
|
||||
const injected = injectWidget('<html><head></head><body>hi</body></html>', widget)
|
||||
assert.ok(injected.includes('id="pna-widget"'))
|
||||
assert.ok(injected.indexOf('id="pna-widget"') < injected.indexOf('</body>'))
|
||||
assert.equal(injectWidget('<html>nobody</html>', widget), '<html>nobody</html>')
|
||||
|
||||
// 12. XSS: hostile `next` value is escaped in the page
|
||||
const hostile = renderLoginPage({ realm: 'T', next: '/" onmouseover="alert(1)', error: '' })
|
||||
assert.ok(!hostile.includes('onmouseover="alert(1)'), 'next not escaped')
|
||||
|
||||
Reference in New Issue
Block a user