feat(account): unlink game accounts on the shard before an account is deleted (MODULE_API 1.20.0)
ACCOUNT_DELETION.md §4.4 (AD10, AD11). api.onUserDeleting queues every linked
account in the new shard_pending_unlinks table, then calls the sidecar's
DELETE /link/{account} (actor web:account-deletion) and drops the mirror on 200/404.
A shard that is away leaves the row pending, retried on WS reconnect and on a live
server.hello; a protected account (403) is refused and listed on Admin -> Shard as
still linked on the shard. A live mob.login without the deleted user's webId clears
the row. coreApi ^1.20.0; core-ref pinned to website#232's merge (7bd93b8).
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01E14m6SuuY6i1vASFeGDBeY
This commit is contained in:
@@ -11,11 +11,15 @@ const uoLinkClient = require('../../utils/uoLinkClient')
|
||||
const uoLinkSocket = require('../../utils/uoLinkSocket')
|
||||
const shardBroadcast = require('../../utils/shardBroadcast')
|
||||
const gameSignup = require('../../utils/gameSignup')
|
||||
const accountDeletion = require('../../utils/accountDeletion')
|
||||
const { activity } = require('../../core')
|
||||
|
||||
const log = require('../../core').logger('admin-uolink')
|
||||
|
||||
// Assemble the masked config + live health + ingestion stats for the panel.
|
||||
// Assemble the masked config + live health + ingestion stats for the panel, and
|
||||
// the game accounts a website account's deletion left linked on the shard
|
||||
// (ACCOUNT_DELETION.md §4.4): `pending` waits for the shard, `refused` is a
|
||||
// protected staff account the shard's staff must clear by hand.
|
||||
async function buildStatus() {
|
||||
const config = await uoLinkConfig.getSafe()
|
||||
const health = await uoLinkClient.health()
|
||||
@@ -24,6 +28,7 @@ async function buildStatus() {
|
||||
health: health.ok ? health.data : { ok: false, error: health.error || `status ${health.status}` },
|
||||
ingest: uoLinkSocket.getState(),
|
||||
sse: shardBroadcast.stats(),
|
||||
pendingUnlinks: await accountDeletion.listForAdmin(),
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -35,7 +35,8 @@ uoLinkRouter.get(
|
||||
// #swagger.tags = ['Admin · Shard']
|
||||
// #swagger.summary = 'Get uo-link config + live status + ingestion stats (admin only)'
|
||||
// #swagger.security = [{ "cookieAuth": [] }, { "bearerAuth": [] }]
|
||||
/* #swagger.responses[200] = { description: 'Masked config, health and ingestion stats', content: { "application/json": { schema: { type: "object", additionalProperties: true } } } } */
|
||||
// #swagger.description = 'pendingUnlinks lists the game accounts a website account deletion left linked on the shard: state pending (the shard was away; retried when the bridge reconnects) or refused (a protected staff account; shard staff clear it by hand). A row goes once the shard reports a login on the account without the deleted user id.'
|
||||
/* #swagger.responses[200] = { description: 'Masked config, health, ingestion stats and pendingUnlinks', content: { "application/json": { schema: { type: "object", additionalProperties: true } } } } */
|
||||
/* #swagger.responses[403] = { description: 'Admin role required', content: { "application/json": { schema: { $ref: "#/components/schemas/Error" } } } } */
|
||||
adminOnly,
|
||||
uoLink.getConfig,
|
||||
|
||||
Reference in New Issue
Block a user