dsh-remote 0.5.0: node settings, session-cookie edge auth, sign-in popup
- Settings → Remote devices → Node: type master|slave (stored in state, beats config role; Restart DSH button under systemd/launchd), origin (read-only: own origin / paired master), 'Master has an auth middleware' toggle - middleware on: a non-DSH answer on the link (login redirect, 401/403, inline HTML) raises auth-required; the UI opens <master>/dsh-remote/signin in a popup, the user signs in to the proxy, one click hands the proxy session cookie back (postMessage, origin-checked, trusted origins only), link retries - edge mode 'cookie': pasted authentik_proxy_… (or a whole Cookie header), rotated proxy cookies persisted back; pair.mjs/install-mac --edge cookie - connectMaster serialised; a failed attempt never clears a finished link - tests: cookie seed/mode, HTML login wall; e2e-signin against a fake proxy
This commit is contained in:
1 parent
78fce8e1ce
commit
bfbc3c66e4
13 files changed
+491
-34
No files matched your search
+31
-2
@@ -78,7 +78,7 @@ test('mode none: a login redirect becomes a clear edge error with a hint', async
|
||||
const { srv } = fakeProxy()
|
||||
const port = await listen(srv)
|
||||
const e = createEdgeAuth({ mode: 'none' }, resolve)
|
||||
await assert.rejects(e.edgeFetch(`http://127.0.0.1:${port}/dsh-remote/enroll`, { method: 'POST' }), (err) => /auth proxy/.test(err.message) && /configure edgeAuth/.test(err.hint))
|
||||
await assert.rejects(e.edgeFetch(`http://127.0.0.1:${port}/dsh-remote/enroll`, { method: 'POST' }), (err) => /auth proxy/.test(err.message) && /sign in through the auth proxy/.test(err.hint))
|
||||
srv.close()
|
||||
})
|
||||
|
||||
@@ -123,7 +123,7 @@ test('oauth2 bad credentials and basic wrong password surface clear errors', asy
|
||||
const o = createEdgeAuth({ mode: 'oauth2', tokenUrl: `http://127.0.0.1:${port}/token`, clientId: 'cid', username: 'svc', passwordRef: 'NOPE' }, async (r) => (r === 'NOPE' ? 'wrong' : undefined))
|
||||
await assert.rejects(o.edgeFetch(`http://127.0.0.1:${port}/x`), /token request failed \(HTTP 400: invalid_grant/)
|
||||
const b = createEdgeAuth({ mode: 'basic', username: 'svc', passwordRef: 'NOPE' }, async () => 'wrong')
|
||||
await assert.rejects(b.edgeFetch(`http://127.0.0.1:${port}/x`), (err) => /refused the request \(HTTP 401\)/.test(err.message) && /check the edgeAuth credentials/.test(err.hint))
|
||||
await assert.rejects(b.edgeFetch(`http://127.0.0.1:${port}/x`), (err) => /refused the request \(HTTP 401\)/.test(err.message) && /rejected the stored credentials/.test(err.hint))
|
||||
const missing = createEdgeAuth({ mode: 'basic', username: 'svc', passwordRef: 'UNSET' }, async () => undefined)
|
||||
await assert.rejects(missing.edgeFetch(`http://127.0.0.1:${port}/x`), /secret "UNSET"/)
|
||||
srv.close()
|
||||
@@ -152,6 +152,35 @@ test('cookie jar: expiry and deletion', () => {
|
||||
assert.equal(j.header(), 'c=3')
|
||||
})
|
||||
|
||||
test('cookie jar seed: accepts name=value, a Cookie: header and multi-line paste; drops dsh-auth-*', () => {
|
||||
const j = new CookieJar()
|
||||
assert.equal(j.seed('Cookie: authentik_proxy_ab12=XYZ; dsh-auth-foo=bar; other="q"'), 2)
|
||||
assert.equal(j.header(), 'authentik_proxy_ab12=XYZ; other=q')
|
||||
j.clear()
|
||||
j.seed('authentik_proxy_ab12=XYZ\nextra=1\n')
|
||||
assert.equal(j.header(), 'authentik_proxy_ab12=XYZ; extra=1')
|
||||
})
|
||||
|
||||
test('mode cookie: pasted cookie passes the proxy, rotated cookie is persisted, HTML page counts as a login wall', async () => {
|
||||
const { srv, sessions } = fakeProxy()
|
||||
const port = await listen(srv)
|
||||
sessions.add('abc123')
|
||||
const saved = []
|
||||
const e = createEdgeAuth({ mode: 'cookie', cookieRef: 'COOK' }, async () => 'Cookie: edge_session=abc123; dsh-auth-x=ignored', { persistCookie: (c) => saved.push(c) })
|
||||
const r = await e.edgeFetch(`http://127.0.0.1:${port}/dsh-remote/enroll`, { method: 'POST' })
|
||||
assert.equal(r.status, 200)
|
||||
assert.deepEqual(e.describe().cookies, ['edge_session'])
|
||||
// A stale cookie → the proxy redirects → clear error with a sign-in hint.
|
||||
const stale = createEdgeAuth({ mode: 'cookie', cookieRef: 'COOK' }, async () => 'edge_session=nope')
|
||||
await assert.rejects(stale.edgeFetch(`http://127.0.0.1:${port}/dsh-remote/enroll`, { method: 'POST' }), (err) => /refused the request/.test(err.message) && /sign in again/.test(err.hint))
|
||||
// An inline HTML sign-in page (200) is not DSH either.
|
||||
const htmlSrv = http.createServer((req, res) => { res.writeHead(200, { 'content-type': 'text/html; charset=utf-8' }); res.end('<html>Sign in</html>') })
|
||||
const hp = await listen(htmlSrv)
|
||||
const none = createEdgeAuth({ mode: 'none' }, resolve)
|
||||
await assert.rejects(none.edgeFetch(`http://127.0.0.1:${hp}/dsh-remote/enroll`, { method: 'POST' }), /HTML page/)
|
||||
srv.close(); htmlSrv.close()
|
||||
})
|
||||
|
||||
test('pair.mjs credentials.yaml ref writer keeps existing records and refs', () => {
|
||||
const before = 'version: 1\nrecords:\n client-connection/browser-session:\n kind: grant\nrefs:\n OMNI_API_KEY: sk-1\n'
|
||||
const after = setRefIn(before, 'DSH_REMOTE_EDGE_PASSWORD', 'p"w')
|
||||
|
||||
Reference in new issue
Block a user