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:
@@ -13089,7 +13089,7 @@
|
||||
"Auth · Me"
|
||||
],
|
||||
"summary": "Unlink an SSO identity (self)",
|
||||
"description": "",
|
||||
"description": "Removes every identity of the provider, or with ?id= the one identity named (a user may link several Steam accounts). Only the sign-in identity goes: a game module link made from it stays (STEAM_SIGNIN.md D393).",
|
||||
"parameters": [
|
||||
{
|
||||
"name": "provider",
|
||||
@@ -13099,6 +13099,15 @@
|
||||
"type": "string"
|
||||
},
|
||||
"description": "Provider id."
|
||||
},
|
||||
{
|
||||
"name": "id",
|
||||
"in": "query",
|
||||
"required": false,
|
||||
"schema": {
|
||||
"type": "integer"
|
||||
},
|
||||
"description": "One identity to unlink (its id from GET /auth/me/account/identities)."
|
||||
}
|
||||
],
|
||||
"responses": {
|
||||
@@ -13113,7 +13122,14 @@
|
||||
}
|
||||
},
|
||||
"400": {
|
||||
"description": "Bad Request"
|
||||
"description": "Validation error",
|
||||
"content": {
|
||||
"application/json": {
|
||||
"schema": {
|
||||
"$ref": "#/components/schemas/ValidationError"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"401": {
|
||||
"description": "Unauthorized"
|
||||
@@ -15467,7 +15483,7 @@
|
||||
"Auth · SSO"
|
||||
],
|
||||
"summary": "OAuth redirect target — completes login or linking",
|
||||
"description": "The provider redirects here with code + state. On success sets the session cookie (login) or links the identity (link), then 302-redirects into /admin. Login is link-only: unknown identities are refused (sso_error=not_linked).",
|
||||
"description": "The provider redirects here with code + state. On success sets the session cookie (login) or links the identity (link), then 302-redirects into /admin. Login is link-only: unknown identities are refused (sso_error=not_linked). Steam (OpenID 2.0) sends openid.* fields instead of code; the server verifies them with Steam (check_authentication) before anything else, and Steam never signs anybody up (STEAM_SIGNIN.md D395). A module may refuse a link (link_error=in_use or refused; MODULE_API 1.17.0).",
|
||||
"parameters": [
|
||||
{
|
||||
"name": "provider",
|
||||
@@ -15476,14 +15492,7 @@
|
||||
"schema": {
|
||||
"type": "string"
|
||||
},
|
||||
"description": "Provider id (e.g. google, discord)."
|
||||
},
|
||||
{
|
||||
"name": "error",
|
||||
"in": "query",
|
||||
"schema": {
|
||||
"type": "string"
|
||||
}
|
||||
"description": "Provider id (e.g. google, discord, steam)."
|
||||
},
|
||||
{
|
||||
"name": "code",
|
||||
@@ -15492,7 +15501,7 @@
|
||||
"schema": {
|
||||
"type": "string"
|
||||
},
|
||||
"description": "OAuth authorization code."
|
||||
"description": "OAuth authorization code (OAuth2/OIDC providers)."
|
||||
},
|
||||
{
|
||||
"name": "state",
|
||||
@@ -15501,7 +15510,50 @@
|
||||
"schema": {
|
||||
"type": "string"
|
||||
},
|
||||
"description": "OAuth state (matched against the tx cookie)."
|
||||
"description": "OAuth state (matched against the tx cookie). For Steam it rides inside openid.return_to and comes back as this parameter."
|
||||
},
|
||||
{
|
||||
"name": "error",
|
||||
"in": "query",
|
||||
"required": false,
|
||||
"schema": {
|
||||
"type": "string"
|
||||
},
|
||||
"description": "OAuth error (the user declined, or the IdP refused)."
|
||||
},
|
||||
{
|
||||
"name": "openid.mode",
|
||||
"in": "query",
|
||||
"required": false,
|
||||
"schema": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"type": {
|
||||
"type": "string",
|
||||
"example": "string"
|
||||
},
|
||||
"enum": {
|
||||
"type": "array",
|
||||
"example": [
|
||||
"id_res",
|
||||
"cancel"
|
||||
],
|
||||
"items": {
|
||||
"type": "string"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"description": "Steam only: id_res with an assertion, or cancel. The other openid.* fields of the assertion (ns, op_endpoint, claimed_id, identity, return_to, response_nonce, assoc_handle, signed, sig) are passed back to Steam to verify."
|
||||
},
|
||||
{
|
||||
"name": "openid.claimed_id",
|
||||
"in": "query",
|
||||
"required": false,
|
||||
"schema": {
|
||||
"type": "string"
|
||||
},
|
||||
"description": "Steam only: https://steamcommunity.com/openid/id/<SteamID64>."
|
||||
}
|
||||
],
|
||||
"responses": {
|
||||
@@ -19827,7 +19879,7 @@
|
||||
},
|
||||
"description": {
|
||||
"type": "string",
|
||||
"example": "Icon hint — the provider kind ('google' | 'discord' | 'oidc' | 'oauth2')."
|
||||
"example": "Icon hint — the provider kind ('google' | 'discord' | 'steam' | 'oidc' | 'oauth2')."
|
||||
},
|
||||
"example": {
|
||||
"type": "string",
|
||||
@@ -19908,6 +19960,7 @@
|
||||
"example": [
|
||||
"google",
|
||||
"discord",
|
||||
"steam",
|
||||
"oidc",
|
||||
"oauth2"
|
||||
],
|
||||
@@ -19965,7 +20018,7 @@
|
||||
},
|
||||
"description": {
|
||||
"type": "string",
|
||||
"example": "Whether a client secret is stored (the secret itself is never returned)."
|
||||
"example": "Whether a client secret is stored (the secret itself is never returned). For steam, the Steam Web API key it cannot be enabled without."
|
||||
},
|
||||
"example": {
|
||||
"type": "boolean",
|
||||
@@ -20047,7 +20100,7 @@
|
||||
},
|
||||
"description": {
|
||||
"type": "string",
|
||||
"example": "True for the fixed google/discord providers."
|
||||
"example": "True for the fixed google/discord/steam providers."
|
||||
},
|
||||
"example": {
|
||||
"type": "boolean",
|
||||
@@ -24740,6 +24793,23 @@
|
||||
"properties": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"id": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"type": {
|
||||
"type": "string",
|
||||
"example": "integer"
|
||||
},
|
||||
"description": {
|
||||
"type": "string",
|
||||
"example": "Identity id, for unlinking one of several (DELETE ...?id=)."
|
||||
},
|
||||
"example": {
|
||||
"type": "number",
|
||||
"example": 12
|
||||
}
|
||||
}
|
||||
},
|
||||
"provider": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
@@ -24774,6 +24844,65 @@
|
||||
}
|
||||
}
|
||||
},
|
||||
"subject": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"type": {
|
||||
"type": "string",
|
||||
"example": "string"
|
||||
},
|
||||
"description": {
|
||||
"type": "string",
|
||||
"example": "The user’s own external id at the provider; for steam, the 17-digit SteamID64."
|
||||
},
|
||||
"example": {
|
||||
"type": "string",
|
||||
"example": "76561197960287930"
|
||||
}
|
||||
}
|
||||
},
|
||||
"display_name": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"type": {
|
||||
"type": "string",
|
||||
"example": "string"
|
||||
},
|
||||
"nullable": {
|
||||
"type": "boolean",
|
||||
"example": true
|
||||
},
|
||||
"description": {
|
||||
"type": "string",
|
||||
"example": "Persona name the provider reported (steam only)."
|
||||
},
|
||||
"example": {
|
||||
"type": "string",
|
||||
"example": "CoolGuy99"
|
||||
}
|
||||
}
|
||||
},
|
||||
"avatar_url": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"type": {
|
||||
"type": "string",
|
||||
"example": "string"
|
||||
},
|
||||
"format": {
|
||||
"type": "string",
|
||||
"example": "uri"
|
||||
},
|
||||
"nullable": {
|
||||
"type": "boolean",
|
||||
"example": true
|
||||
},
|
||||
"description": {
|
||||
"type": "string",
|
||||
"example": "Avatar on the provider’s CDN (steam only)."
|
||||
}
|
||||
}
|
||||
},
|
||||
"linked_at": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
|
||||
Reference in New Issue
Block a user