Files
esports/scripts/migrations/0002-auth-connections.sql

38 lines
2.0 KiB
SQL

-- Additive migration: old releases can still read their original email column.
-- Runtime identity is always account(provider_id, account_id), never an email pattern.
ALTER TABLE "user" ADD COLUMN IF NOT EXISTS contact_email text;
ALTER TABLE "user" ADD COLUMN IF NOT EXISTS root_admin boolean NOT NULL DEFAULT false;
ALTER TABLE "user" ADD COLUMN IF NOT EXISTS merged_into_user_id text;
ALTER TABLE account ADD COLUMN IF NOT EXISTS profile jsonb;
UPDATE "user" SET contact_email = lower(email)
WHERE contact_email IS NULL AND email !~* '@(osu\.local|discord\.local|identity\.invalid)$';
CREATE UNIQUE INDEX IF NOT EXISTS user_contact_email_unique ON "user" (contact_email);
-- Fail the transaction for conflicting connections; never guess which user owns one.
CREATE UNIQUE INDEX IF NOT EXISTS account_provider_identity_idx ON account (provider_id, account_id);
CREATE UNIQUE INDEX IF NOT EXISTS account_user_provider_idx ON account (user_id, provider_id);
-- Profile backfill is best effort; OAuth refreshes it on the next successful sign-in.
UPDATE account a SET profile = jsonb_build_object(
'username', u.name, 'image', u.image, 'email', null, 'emailVerified', false,
'countryCode', u.country_code, 'globalRank', r.osu_rank_at_seed
)
FROM "user" u LEFT JOIN player_rating r ON r.user_id = u.id
WHERE a.user_id = u.id AND a.provider_id IN ('osu', 'discord') AND a.profile IS NULL;
-- Repair solo roster snapshots only where ownership is unambiguous. Match discovery
-- and authorization can then use the same persisted participant roster.
INSERT INTO team_member (team_id, user_id, role)
SELECT t.id, t.owner_id, 'owner' FROM team t
JOIN "user" u ON u.id = t.owner_id
WHERE t.is_personal AND NOT EXISTS (
SELECT 1 FROM team_member tm WHERE tm.team_id = t.id AND tm.user_id = t.owner_id
);
INSERT INTO match_participant_player (participant_id, user_id)
SELECT p.id, t.owner_id FROM match_participant p JOIN team t ON t.id = p.team_id
JOIN "user" u ON u.id = t.owner_id
WHERE t.is_personal AND NOT EXISTS (
SELECT 1 FROM match_participant_player pp WHERE pp.participant_id = p.id
);