Ties an in-game account to a website user and gates reads on ownership.
- schema: shard_account_links (account PK → user_id, char_name, linked_at;
FK users ON DELETE CASCADE) — the site-side mirror of the sidecar's
authoritative link.
- model/shardLinks: upsert/list/ownership-check/getByAccount/unlink.
- player/shard.controller.js:
- POST /player/shard/link — confirm a one-time [link code via
uoLinkClient.confirmLink(code, req.user.id); on link.ok mirror the link and
activity.log it; bad/expired codes → 400, shard down → 503.
- GET /player/shard/accounts — the caller's linked accounts.
- GET /player/shard/roster/:account and /vendors/:account — live round-trips,
ownership-checked against the mirror (403 otherwise), 503 on shard restart.
- player.routes.js: mounted under the existing requireRole('player') gate with
express-validator guards + #swagger annotations; new "Player · Shard" tag and
ShardLinkRequest/ShardLinkResult/ShardLink schemas; spec regenerated.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_011qPmpmVH1xGCiZoz9m9vW3
35 lines
994 B
JavaScript
35 lines
994 B
JavaScript
// Site-side mirror of in-game-account → website-user links. The sidecar owns the
|
|
// authoritative link (it tags the game account on /link/confirm); this model
|
|
// records it locally so the player portal can list links and enforce ownership.
|
|
|
|
const db = require('./shardLinks.db')
|
|
|
|
function toSafe(row) {
|
|
if (!row) return null
|
|
return {
|
|
account: row.account,
|
|
userId: row.user_id,
|
|
charName: row.char_name || null,
|
|
linkedAt: row.linked_at,
|
|
}
|
|
}
|
|
|
|
async function link({ account, userId, charName }) {
|
|
return toSafe(await db.upsert({ account, userId, charName }))
|
|
}
|
|
|
|
async function listForUser(userId) {
|
|
const rows = await db.listByUser(userId)
|
|
return rows.map(toSafe)
|
|
}
|
|
|
|
const ownsAccount = (account, userId) => db.isOwnedBy(account, userId)
|
|
|
|
async function getByAccount(account) {
|
|
return toSafe(await db.getByAccount(account))
|
|
}
|
|
|
|
const unlink = (account, userId) => db.remove(account, userId)
|
|
|
|
module.exports = { link, listForUser, ownsAccount, getByAccount, unlink }
|