feat: complete registration invitation and auth redesign
This commit is contained in:
+78
-4
@@ -581,13 +581,87 @@ CREATE TABLE IF NOT EXISTS tinode.im_user_profiles (
|
||||
|
||||
-- Existing database migration (the application performs the same migration
|
||||
-- idempotently at startup):
|
||||
-- 1. Add im_users.phone VARCHAR(32) NULL and a UNIQUE index.
|
||||
-- 2. Add im_user_profiles.email VARCHAR(128) NOT NULL DEFAULT ''.
|
||||
-- 3. Backfill phone/email from validated im_credentials first, then use
|
||||
-- 1. Add im_users.phone VARCHAR(32) NULL and im_users.username VARCHAR(32).
|
||||
-- 2. Backfill username from im_auth.uname after removing the basic: prefix;
|
||||
-- use phone or reserved_<id> only when no Basic login exists.
|
||||
-- 3. Add im_user_profiles.email VARCHAR(128) NOT NULL DEFAULT ''.
|
||||
-- 4. Backfill phone/email from validated im_credentials first, then use
|
||||
-- tel:/email: rows in im_usertags as a legacy fallback.
|
||||
-- 4. Drop im_usertags and im_users.tags only after the backfill is verified.
|
||||
-- 5. Verify uniqueness, then make username NOT NULL and add UNIQUE(username).
|
||||
-- 6. Drop im_auth.uname and im_auth.scheme; add UNIQUE(userid).
|
||||
-- 7. Drop im_usertags and im_users.tags only after the backfill is verified.
|
||||
-- im_topics.tags and im_topictags are topic discovery data and must be retained.
|
||||
|
||||
CREATE TABLE IF NOT EXISTS hotgo.im_registration_invite_batches (
|
||||
id BIGINT NOT NULL,
|
||||
tenant_id BIGINT NOT NULL,
|
||||
quantity INT UNSIGNED NOT NULL,
|
||||
idempotency_key VARCHAR(128) NOT NULL,
|
||||
expires_at DATETIME(3) NOT NULL,
|
||||
created_by BIGINT NOT NULL,
|
||||
remark VARCHAR(255) NOT NULL DEFAULT '',
|
||||
created_at DATETIME(3) NOT NULL,
|
||||
updated_at DATETIME(3) NOT NULL,
|
||||
PRIMARY KEY (id),
|
||||
UNIQUE INDEX uk_im_registration_invite_batch_tenant_idempotency (tenant_id, idempotency_key),
|
||||
INDEX idx_im_registration_invite_batch_tenant_created (tenant_id, created_at)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci;
|
||||
|
||||
CREATE TABLE IF NOT EXISTS hotgo.im_registration_invite_codes (
|
||||
id BIGINT NOT NULL,
|
||||
tenant_id BIGINT NOT NULL,
|
||||
batch_id BIGINT,
|
||||
code CHAR(5) CHARACTER SET ascii COLLATE ascii_bin NOT NULL,
|
||||
status VARCHAR(16) NOT NULL DEFAULT 'active',
|
||||
expires_at DATETIME(3) NOT NULL,
|
||||
usage_count INT UNSIGNED NOT NULL DEFAULT 0,
|
||||
last_used_at DATETIME(3),
|
||||
created_by BIGINT NOT NULL,
|
||||
remark VARCHAR(255) NOT NULL DEFAULT '',
|
||||
created_at DATETIME(3) NOT NULL,
|
||||
updated_at DATETIME(3) NOT NULL,
|
||||
PRIMARY KEY (id),
|
||||
UNIQUE INDEX uk_im_registration_invite_code_tenant (tenant_id, code),
|
||||
INDEX idx_im_registration_invite_tenant_status_expires (tenant_id, status, expires_at),
|
||||
INDEX idx_im_registration_invite_tenant_batch (tenant_id, batch_id),
|
||||
INDEX idx_im_registration_invite_tenant_created (tenant_id, created_at)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci;
|
||||
|
||||
CREATE TABLE IF NOT EXISTS tinode.im_registration_invite_uses (
|
||||
id BIGINT NOT NULL,
|
||||
invite_code_id BIGINT NOT NULL,
|
||||
user_id BIGINT NOT NULL,
|
||||
request_id VARCHAR(64) NOT NULL,
|
||||
used_at DATETIME(3) NOT NULL,
|
||||
PRIMARY KEY (id),
|
||||
INDEX idx_im_registration_invite_use_code (invite_code_id),
|
||||
UNIQUE INDEX uk_im_registration_invite_use_user (user_id),
|
||||
INDEX idx_im_registration_invite_use_request (request_id)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci;
|
||||
|
||||
-- Legacy default-tenant migration. For additional tenant databases, repeat
|
||||
-- this copy with that database name and its hotgo.im_tenant.id before drop.
|
||||
SET @im_sql := IF(
|
||||
(SELECT COUNT(*) FROM information_schema.TABLES WHERE TABLE_SCHEMA='tinode' AND TABLE_NAME='im_registration_invite_batches') > 0,
|
||||
'INSERT INTO hotgo.im_registration_invite_batches (id,tenant_id,quantity,idempotency_key,expires_at,created_by,remark,created_at,updated_at) SELECT id,1,quantity,idempotency_key,expires_at,created_by,remark,created_at,updated_at FROM tinode.im_registration_invite_batches ON DUPLICATE KEY UPDATE updated_at=VALUES(updated_at)',
|
||||
'SELECT 1'
|
||||
);
|
||||
PREPARE im_stmt FROM @im_sql;
|
||||
EXECUTE im_stmt;
|
||||
DEALLOCATE PREPARE im_stmt;
|
||||
|
||||
SET @im_sql := IF(
|
||||
(SELECT COUNT(*) FROM information_schema.TABLES WHERE TABLE_SCHEMA='tinode' AND TABLE_NAME='im_registration_invite_codes') > 0,
|
||||
'INSERT INTO hotgo.im_registration_invite_codes (id,tenant_id,batch_id,code,status,expires_at,usage_count,last_used_at,created_by,remark,created_at,updated_at) SELECT c.id,1,c.batch_id,c.code,CASE WHEN c.status=''used'' THEN IF(c.expires_at<=NOW(3),''expired'',''active'') ELSE c.status END,c.expires_at,COUNT(u.id),MAX(u.used_at),c.created_by,c.remark,c.created_at,c.updated_at FROM tinode.im_registration_invite_codes c LEFT JOIN tinode.im_registration_invite_uses u ON u.invite_code_id=c.id GROUP BY c.id ON DUPLICATE KEY UPDATE usage_count=VALUES(usage_count),last_used_at=VALUES(last_used_at),updated_at=VALUES(updated_at)',
|
||||
'SELECT 1'
|
||||
);
|
||||
PREPARE im_stmt FROM @im_sql;
|
||||
EXECUTE im_stmt;
|
||||
DEALLOCATE PREPARE im_stmt;
|
||||
|
||||
DROP TABLE IF EXISTS tinode.im_registration_invite_codes;
|
||||
DROP TABLE IF EXISTS tinode.im_registration_invite_batches;
|
||||
|
||||
CREATE TABLE IF NOT EXISTS tinode.im_user_privacy_settings (
|
||||
id BIGINT NOT NULL,
|
||||
user_id BIGINT NOT NULL,
|
||||
|
||||
Reference in New Issue
Block a user