Steam is a built-in provider beside Google and Discord (STEAM_SIGNIN.md, D392-D396). OpenID 2.0: the assertion is verified server to server with check_authentication, return_to must match byte for byte, and the claimed id must be a 17-digit SteamID64. A Steam Web API key is required to enable it (D394); persona name and avatar are stored on the identity and refreshed at each sign-in, and a failed lookup never blocks one. Steam never signs anybody up (D395), on the web or the mobile bridge. Several Steam accounts may be linked; DELETE /auth/me/account/identities/:provider takes ?id= to unlink one. MODULE_API 1.17.0: ctx.identities.list, api.onIdentityLinking (refuse-only, fails closed, module text never shown) and api.onIdentityLinked. No unlink hook (D393). Schema additive; OpenAPI, routes and engagement manifests regenerated with no modules installed. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01E14m6SuuY6i1vASFeGDBeY
54 lines
2.7 KiB
JavaScript
54 lines
2.7 KiB
JavaScript
process.env.JWT_SECRET = process.env.JWT_SECRET || 'test-secret'
|
|
process.env.SECRET_ENC_KEY = process.env.SECRET_ENC_KEY || 'unit-test-enc-key'
|
|
process.env.DB_HOST = '127.0.0.1'
|
|
process.env.DB_PORT = '59999'
|
|
|
|
const { test, after } = require('node:test')
|
|
const assert = require('node:assert/strict')
|
|
|
|
const registry = require('../src/auth/providers/registry')
|
|
const authProvidersModel = require('../src/model/authProviders/authProviders.model')
|
|
const db = require('../src/utils/db')
|
|
|
|
after(() => db.close())
|
|
|
|
test('validateConfig: built-in needs client_id + secret', () => {
|
|
assert.equal(registry.validateConfig({ kind: 'google', client_id: 'x', client_secret_enc: 'e' }).valid, true)
|
|
assert.deepEqual(registry.validateConfig({ kind: 'google', client_id: 'x' }).missing, ['client_secret'])
|
|
assert.deepEqual(registry.validateConfig({ kind: 'google' }).missing, ['client_id', 'client_secret'])
|
|
})
|
|
|
|
test('validateConfig: custom OIDC also needs the endpoint URLs', () => {
|
|
const complete = {
|
|
kind: 'oidc', client_id: 'x', client_secret_enc: 'e',
|
|
authorize_url: 'a', token_url: 't', userinfo_url: 'u',
|
|
}
|
|
assert.equal(registry.validateConfig(complete).valid, true)
|
|
const noUrls = { kind: 'oidc', client_id: 'x', client_secret_enc: 'e' }
|
|
assert.deepEqual(registry.validateConfig(noUrls).missing, ['authorize_url', 'token_url', 'userinfo_url'])
|
|
})
|
|
|
|
test('listConfigured always includes every built-in with health', async () => {
|
|
authProvidersModel.list = async () => [] // no rows yet
|
|
const out = await registry.listConfigured()
|
|
const ids = out.map((p) => p.id)
|
|
assert.deepEqual(ids, ['google', 'discord', 'steam'])
|
|
assert.equal(out[0].builtin, true)
|
|
assert.equal(out[0].enabled, 0)
|
|
assert.equal(out[0].health.valid, false) // unconfigured
|
|
})
|
|
|
|
test('listEnabledValid returns only enabled+valid, shaped and sorted by priority', async () => {
|
|
authProvidersModel.list = async () => [
|
|
{ id: 'discord', kind: 'discord', name: 'Discord', enabled: 1, client_id: 'd', client_secret_enc: 'e', priority: 2 },
|
|
{ id: 'google', kind: 'google', name: 'Google', enabled: 1, client_id: 'g', client_secret_enc: 'e', priority: 1 },
|
|
{ id: 'brokenidp', kind: 'oidc', name: 'Broken', enabled: 1, client_id: 'x', client_secret_enc: 'e', priority: 0 }, // missing URLs → hidden
|
|
{ id: 'authentik', kind: 'oidc', name: 'Authentik', enabled: 0, client_id: 'x', client_secret_enc: 'e', authorize_url: 'a', token_url: 't', userinfo_url: 'u', priority: 3 }, // disabled → hidden
|
|
]
|
|
const out = await registry.listEnabledValid()
|
|
assert.deepEqual(out.map((p) => p.id), ['google', 'discord']) // sorted by priority, broken/disabled excluded
|
|
assert.deepEqual(out[0], {
|
|
id: 'google', name: 'Google', icon: 'google', loginUrl: '/api/v1/auth/sso/google/start', priority: 1,
|
|
})
|
|
})
|