You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
synctv/migrations/20260426006_create_user_reg...

148 lines
5.8 KiB
SQL

CREATE TABLE IF NOT EXISTS user_registration_requests (
id BIGINT GENERATED BY DEFAULT AS IDENTITY PRIMARY KEY,
username VARCHAR(50) NOT NULL,
email VARCHAR(255),
opaque_record BYTEA,
opaque_credential_identifier BYTEA,
opaque_ciphersuite VARCHAR(64),
opaque_server_setup_version INTEGER,
oauth2_provider_type SMALLINT,
oauth2_provider_instance_name VARCHAR(64),
oauth2_provider_issuer TEXT,
oauth2_provider_user_id VARCHAR(255),
oauth2_provider_username VARCHAR(255),
oauth2_avatar_url TEXT,
webauthn_credential_id BYTEA,
webauthn_passkey JSONB,
webauthn_credential_name VARCHAR(100),
signup_method SMALLINT NOT NULL,
status SMALLINT NOT NULL,
requested_at TIMESTAMPTZ NOT NULL DEFAULT CURRENT_TIMESTAMP,
reviewed_at TIMESTAMPTZ,
reviewed_by BIGINT REFERENCES users(id) ON DELETE RESTRICT,
rejection_reason TEXT,
CONSTRAINT user_registration_requests_email_not_empty
CHECK (email IS NULL OR length(trim(email)) > 0),
CONSTRAINT user_registration_requests_opaque_material_group_complete
CHECK (
(
opaque_record IS NULL
AND opaque_credential_identifier IS NULL
AND opaque_ciphersuite IS NULL
AND opaque_server_setup_version IS NULL
)
OR (
opaque_record IS NOT NULL
AND opaque_credential_identifier IS NOT NULL
AND opaque_ciphersuite IS NOT NULL
AND opaque_server_setup_version IS NOT NULL
)
),
CONSTRAINT user_registration_requests_opaque_record_not_empty
CHECK (opaque_record IS NULL OR length(opaque_record) > 0),
CONSTRAINT user_registration_requests_opaque_identifier_not_empty
CHECK (opaque_credential_identifier IS NULL OR length(opaque_credential_identifier) > 0),
CONSTRAINT user_registration_requests_opaque_ciphersuite_not_empty
CHECK (opaque_ciphersuite IS NULL OR length(trim(opaque_ciphersuite)) > 0),
CONSTRAINT user_registration_requests_opaque_setup_version_positive
CHECK (
opaque_server_setup_version IS NULL
OR opaque_server_setup_version > 0
),
CONSTRAINT user_registration_requests_webauthn_name_not_empty
CHECK (
webauthn_credential_name IS NULL
OR length(trim(webauthn_credential_name)) > 0
),
CONSTRAINT user_registration_requests_webauthn_passkey_object
CHECK (
webauthn_passkey IS NULL
OR jsonb_typeof(webauthn_passkey) = 'object'
),
CONSTRAINT user_registration_requests_webauthn_material_group_complete
CHECK (
(
webauthn_credential_id IS NULL
AND webauthn_passkey IS NULL
AND webauthn_credential_name IS NULL
)
OR (
webauthn_credential_id IS NOT NULL
AND webauthn_passkey IS NOT NULL
)
),
CONSTRAINT user_registration_requests_oauth2_material_group_complete
CHECK (
(
oauth2_provider_type IS NULL
AND oauth2_provider_instance_name IS NULL
AND oauth2_provider_user_id IS NULL
)
OR (
oauth2_provider_type IS NOT NULL
AND oauth2_provider_instance_name IS NOT NULL
AND oauth2_provider_user_id IS NOT NULL
)
),
CONSTRAINT user_registration_requests_oauth2_instance_not_empty
CHECK (
oauth2_provider_instance_name IS NULL
OR length(trim(oauth2_provider_instance_name)) > 0
),
CONSTRAINT user_registration_requests_oauth2_user_id_not_empty
CHECK (
oauth2_provider_user_id IS NULL
OR length(trim(oauth2_provider_user_id)) > 0
),
CONSTRAINT user_registration_requests_auth_material_present
CHECK (
opaque_record IS NOT NULL
OR oauth2_provider_user_id IS NOT NULL
OR webauthn_credential_id IS NOT NULL
),
CONSTRAINT user_registration_requests_auth_material_exclusive
CHECK (
((opaque_record IS NOT NULL)::int
+ (oauth2_provider_user_id IS NOT NULL)::int
+ (webauthn_credential_id IS NOT NULL)::int) = 1
),
CONSTRAINT user_registration_requests_rejection_reason_not_empty
CHECK (
rejection_reason IS NULL
OR length(trim(rejection_reason)) > 0
)
);
CREATE INDEX IF NOT EXISTS idx_user_registration_requests_status_requested
ON user_registration_requests(status, requested_at DESC);
CREATE INDEX IF NOT EXISTS idx_user_registration_requests_pending_username
ON user_registration_requests(LOWER(username))
WHERE reviewed_at IS NULL;
CREATE INDEX IF NOT EXISTS idx_user_registration_requests_pending_email
ON user_registration_requests(LOWER(email))
WHERE reviewed_at IS NULL
AND email IS NOT NULL;
CREATE INDEX IF NOT EXISTS idx_user_registration_requests_pending_oauth2_identity
ON user_registration_requests(oauth2_provider_instance_name, oauth2_provider_user_id)
WHERE reviewed_at IS NULL
AND oauth2_provider_instance_name IS NOT NULL
AND oauth2_provider_user_id IS NOT NULL;
CREATE INDEX IF NOT EXISTS idx_user_registration_requests_pending_oauth2_type
ON user_registration_requests(oauth2_provider_type)
WHERE reviewed_at IS NULL
AND oauth2_provider_type IS NOT NULL;
CREATE UNIQUE INDEX IF NOT EXISTS idx_user_registration_requests_pending_webauthn_credential
ON user_registration_requests(webauthn_credential_id)
WHERE reviewed_at IS NULL
AND webauthn_credential_id IS NOT NULL;
CREATE INDEX IF NOT EXISTS idx_user_registration_requests_reviewed_by
ON user_registration_requests(reviewed_by)
WHERE reviewed_by IS NOT NULL;