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
36 lines
1.5 KiB
JavaScript
36 lines
1.5 KiB
JavaScript
// Account-linking store: maps external SSO identities to internal users. Thin
|
|
// logic layer over userIdentities.db (mirrors the users model split).
|
|
|
|
const db = require('./userIdentities.db')
|
|
|
|
// The link-only login lookup. Returns the identity row (with user_id) or null.
|
|
async function findByProviderSubject(provider, subject) {
|
|
return db.findByProviderSubject(provider, subject)
|
|
}
|
|
|
|
// Identities linked to a user (Account page).
|
|
async function listForUser(userId) {
|
|
return db.listForUser(userId)
|
|
}
|
|
|
|
// Link an external identity to an internal user. Returns the new row id. The
|
|
// (provider, subject) UNIQUE constraint enforces one-identity-one-user at the DB.
|
|
// `displayName` / `avatarUrl` are set by providers that report them (Steam);
|
|
// the others leave them null.
|
|
async function link({ userId, provider, subject, email, displayName, avatarUrl }) {
|
|
return db.insert({ userId, provider, subject, email, displayName, avatarUrl })
|
|
}
|
|
|
|
// Refresh a linked identity's name and avatar from a sign-in's profile.
|
|
async function refreshProfile(identityId, { displayName, avatarUrl } = {}) {
|
|
return db.updateProfile(identityId, { displayName, avatarUrl })
|
|
}
|
|
|
|
// Unlink a provider from a user: every identity of it, or the one `identityId`
|
|
// names. Returns rows removed (0 if nothing was linked).
|
|
async function unlink(userId, provider, identityId = null) {
|
|
return db.deleteForUserProvider(userId, provider, identityId)
|
|
}
|
|
|
|
module.exports = { findByProviderSubject, listForUser, link, refreshProfile, unlink }
|