38 lines
1.2 KiB
SQL
38 lines
1.2 KiB
SQL
-- Multiple provider identities may resolve to one canonical app user.
|
|
-- Alias writes are owner-only: the runtime app role can read through RLS but
|
|
-- receives no INSERT/UPDATE/DELETE policy.
|
|
|
|
CREATE TABLE IF NOT EXISTS app.auth_identity_alias (
|
|
external_id TEXT PRIMARY KEY
|
|
CHECK (external_id ~ '^[a-z0-9_-]+:.+$'),
|
|
user_id UUID NOT NULL
|
|
REFERENCES app.app_user(user_id) ON DELETE RESTRICT,
|
|
source_user_id UUID
|
|
REFERENCES app.app_user(user_id) ON DELETE SET NULL,
|
|
linked_at TIMESTAMPTZ NOT NULL DEFAULT now(),
|
|
linked_by TEXT NOT NULL,
|
|
reason TEXT NOT NULL,
|
|
CHECK (source_user_id IS NULL OR source_user_id <> user_id)
|
|
);
|
|
|
|
CREATE INDEX IF NOT EXISTS idx_auth_identity_alias_user
|
|
ON app.auth_identity_alias(user_id, linked_at DESC);
|
|
|
|
ALTER TABLE app.auth_identity_alias ENABLE ROW LEVEL SECURITY;
|
|
|
|
DROP POLICY IF EXISTS p_auth_identity_alias_select
|
|
ON app.auth_identity_alias;
|
|
CREATE POLICY p_auth_identity_alias_select
|
|
ON app.auth_identity_alias
|
|
FOR SELECT
|
|
USING (true);
|
|
|
|
ALTER TABLE app.auth_session
|
|
ADD COLUMN IF NOT EXISTS login_email TEXT NOT NULL DEFAULT '';
|
|
|
|
UPDATE app.auth_session AS s
|
|
SET login_email = lower(u.email)
|
|
FROM app.app_user AS u
|
|
WHERE u.user_id = s.user_id
|
|
AND s.login_email = ''
|
|
AND u.email IS NOT NULL;
|