feat(auth): sign in with Steam (MODULE_API 1.17.0)
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
This commit is contained in:
@@ -1,6 +1,6 @@
|
||||
// ── Admin: auth provider configuration ─────────────────────────────────────
|
||||
//
|
||||
// CRUD for SSO providers. Built-ins (google, discord) are configured here too but
|
||||
// CRUD for SSO providers. Built-ins (google, discord, steam) are configured here too but
|
||||
// can only be enabled/disabled and given a client id/secret — their kind, name,
|
||||
// and endpoints are fixed in code and cannot be edited or deleted. Custom
|
||||
// (oidc/oauth2) providers are fully editable.
|
||||
@@ -80,6 +80,18 @@ async function update(req, res) {
|
||||
// Built-ins: kind/name/priority are fixed; only enable + credentials change.
|
||||
const meta = registry.BUILTINS.find((x) => x.id === id)
|
||||
fields = { kind: meta.kind, name: meta.name, priority: meta.priority, enabled: b.enabled, clientId: b.clientId, secret: b.secret }
|
||||
if (meta.kind === 'steam') {
|
||||
// Steam has no client id; its secret is the Steam Web API key, and it
|
||||
// cannot be enabled without one (D394) — refused here, with a sentence,
|
||||
// rather than saved as an "Incomplete" provider nobody can use.
|
||||
fields.clientId = undefined
|
||||
if (b.enabled === true && !b.secret) {
|
||||
const current = await authProviders.get(id)
|
||||
if (!current || !current.client_secret_enc) {
|
||||
return res.status(400).json({ message: 'Steam needs a Steam Web API key before it can be enabled.' })
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if (!(await authProviders.get(id))) {
|
||||
return res.status(404).json({ message: 'Provider not found.' })
|
||||
|
||||
@@ -59,11 +59,12 @@ providersRouter.put(
|
||||
'/providers/:id',
|
||||
// #swagger.tags = ['Admin · Auth Providers']
|
||||
// #swagger.summary = 'Update an SSO provider (admin only)'
|
||||
// #swagger.description = 'Built-ins (google, discord, steam) take only enabled + credentials. Steam has no client id: its secret is a Steam Web API key, and enabling Steam without one stored or given is refused with 400 (STEAM_SIGNIN.md D394).'
|
||||
// #swagger.security = [{ "cookieAuth": [] }, { "bearerAuth": [] }]
|
||||
// #swagger.parameters['id'] = { in: 'path', required: true, schema: { type: 'string' }, description: 'Provider id.' }
|
||||
/* #swagger.requestBody = { content: { "application/json": { schema: { $ref: "#/components/schemas/ProviderCreateRequest" } } } } */
|
||||
/* #swagger.responses[200] = { description: 'Updated provider', content: { "application/json": { schema: { $ref: "#/components/schemas/ProviderConfig" } } } } */
|
||||
/* #swagger.responses[400] = { description: 'Validation error', content: { "application/json": { schema: { $ref: "#/components/schemas/ValidationError" } } } } */
|
||||
/* #swagger.responses[400] = { description: 'Validation error, or Steam enabled without a Steam Web API key', content: { "application/json": { schema: { $ref: "#/components/schemas/ValidationError" } } } } */
|
||||
/* #swagger.responses[401] = { description: 'Not authenticated', content: { "application/json": { schema: { $ref: "#/components/schemas/Error" } } } } */
|
||||
/* #swagger.responses[403] = { description: 'Admin role required', content: { "application/json": { schema: { $ref: "#/components/schemas/Error" } } } } */
|
||||
/* #swagger.responses[404] = { description: 'Provider not found', content: { "application/json": { schema: { $ref: "#/components/schemas/Error" } } } } */
|
||||
|
||||
Reference in New Issue
Block a user