feat: add im auth verification flows
This commit is contained in:
+102
-1
@@ -41,7 +41,7 @@ type adapter struct {
|
||||
}
|
||||
|
||||
const (
|
||||
adpVersion = 117
|
||||
adpVersion = 118
|
||||
adapterName = "mysql"
|
||||
|
||||
defaultDSN = "root:@tcp(localhost:3306)/tinode?parseTime=true"
|
||||
@@ -375,6 +375,34 @@ func (a *adapter) CreateDb(reset bool) error {
|
||||
return err
|
||||
}
|
||||
|
||||
if _, err = tx.Exec(
|
||||
`CREATE TABLE im_verification_codes(
|
||||
id BIGINT NOT NULL AUTO_INCREMENT,
|
||||
tenant_id BIGINT NOT NULL,
|
||||
challenge_id VARCHAR(64) NOT NULL,
|
||||
scene VARCHAR(32) NOT NULL,
|
||||
phone_hash CHAR(64) NOT NULL,
|
||||
phone_mask VARCHAR(32) NOT NULL,
|
||||
target_user BIGINT,
|
||||
code_hash CHAR(64) NOT NULL,
|
||||
verification_token_hash CHAR(64),
|
||||
state SMALLINT NOT NULL,
|
||||
attempts INT NOT NULL DEFAULT 0,
|
||||
max_attempts INT NOT NULL,
|
||||
expires_at DATETIME(3) NOT NULL,
|
||||
resend_after DATETIME(3) NOT NULL,
|
||||
verified_at DATETIME(3),
|
||||
consumed_at DATETIME(3),
|
||||
created_at DATETIME(3) NOT NULL DEFAULT CURRENT_TIMESTAMP(3),
|
||||
updated_at DATETIME(3) NOT NULL DEFAULT CURRENT_TIMESTAMP(3) ON UPDATE CURRENT_TIMESTAMP(3),
|
||||
PRIMARY KEY(id),
|
||||
UNIQUE INDEX uk_im_verification_tenant_challenge(tenant_id, challenge_id),
|
||||
INDEX idx_im_verification_tenant_scene_phone_state(tenant_id, scene, phone_hash, state, expires_at),
|
||||
CONSTRAINT fk_im_verification_tenant FOREIGN KEY(tenant_id) REFERENCES im_tenant(id) ON DELETE CASCADE
|
||||
)`); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if _, err = tx.Exec(
|
||||
`INSERT INTO im_tenant(code,name,tenant_desc,state,created_by,updated_by)
|
||||
VALUES('default','Default Tenant',NULL,?,0,0)`, t.TenantStateActive); err != nil {
|
||||
@@ -401,6 +429,20 @@ func (a *adapter) CreateDb(reset bool) error {
|
||||
return err
|
||||
}
|
||||
|
||||
if _, err = tx.Exec(
|
||||
`CREATE TABLE im_user_security(
|
||||
tenant_id BIGINT NOT NULL,
|
||||
user_id BIGINT NOT NULL,
|
||||
auth_version INT NOT NULL DEFAULT 1,
|
||||
password_updated_at DATETIME(3),
|
||||
created_at DATETIME(3) NOT NULL DEFAULT CURRENT_TIMESTAMP(3),
|
||||
updated_at DATETIME(3) NOT NULL DEFAULT CURRENT_TIMESTAMP(3) ON UPDATE CURRENT_TIMESTAMP(3),
|
||||
PRIMARY KEY(tenant_id,user_id),
|
||||
CONSTRAINT fk_im_user_security_tenant FOREIGN KEY(tenant_id) REFERENCES im_tenant(id) ON DELETE CASCADE
|
||||
)`); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// Indexed user tags.
|
||||
if _, err = tx.Exec(
|
||||
`CREATE TABLE usertags(
|
||||
@@ -935,6 +977,60 @@ func (a *adapter) UpgradeDb() error {
|
||||
}
|
||||
}
|
||||
|
||||
if a.version == 117 {
|
||||
if _, err := a.db.Exec(
|
||||
`CREATE TABLE im_verification_codes(
|
||||
id BIGINT NOT NULL AUTO_INCREMENT,
|
||||
tenant_id BIGINT NOT NULL,
|
||||
challenge_id VARCHAR(64) NOT NULL,
|
||||
scene VARCHAR(32) NOT NULL,
|
||||
phone_hash CHAR(64) NOT NULL,
|
||||
phone_mask VARCHAR(32) NOT NULL,
|
||||
target_user BIGINT,
|
||||
code_hash CHAR(64) NOT NULL,
|
||||
verification_token_hash CHAR(64),
|
||||
state SMALLINT NOT NULL,
|
||||
attempts INT NOT NULL DEFAULT 0,
|
||||
max_attempts INT NOT NULL,
|
||||
expires_at DATETIME(3) NOT NULL,
|
||||
resend_after DATETIME(3) NOT NULL,
|
||||
verified_at DATETIME(3),
|
||||
consumed_at DATETIME(3),
|
||||
created_at DATETIME(3) NOT NULL DEFAULT CURRENT_TIMESTAMP(3),
|
||||
updated_at DATETIME(3) NOT NULL DEFAULT CURRENT_TIMESTAMP(3) ON UPDATE CURRENT_TIMESTAMP(3),
|
||||
PRIMARY KEY(id),
|
||||
UNIQUE INDEX uk_im_verification_tenant_challenge(tenant_id, challenge_id),
|
||||
INDEX idx_im_verification_tenant_scene_phone_state(tenant_id, scene, phone_hash, state, expires_at),
|
||||
CONSTRAINT fk_im_verification_tenant FOREIGN KEY(tenant_id) REFERENCES im_tenant(id) ON DELETE CASCADE
|
||||
)`); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if _, err := a.db.Exec(
|
||||
`CREATE TABLE im_user_security(
|
||||
tenant_id BIGINT NOT NULL,
|
||||
user_id BIGINT NOT NULL,
|
||||
auth_version INT NOT NULL DEFAULT 1,
|
||||
password_updated_at DATETIME(3),
|
||||
created_at DATETIME(3) NOT NULL DEFAULT CURRENT_TIMESTAMP(3),
|
||||
updated_at DATETIME(3) NOT NULL DEFAULT CURRENT_TIMESTAMP(3) ON UPDATE CURRENT_TIMESTAMP(3),
|
||||
PRIMARY KEY(tenant_id,user_id),
|
||||
CONSTRAINT fk_im_user_security_tenant FOREIGN KEY(tenant_id) REFERENCES im_tenant(id) ON DELETE CASCADE
|
||||
)`); err != nil {
|
||||
return err
|
||||
}
|
||||
if _, err := a.db.Exec(
|
||||
`INSERT INTO im_user_security(tenant_id,user_id,auth_version,created_at,updated_at)
|
||||
SELECT tenant_id,id,1,updatedat,updatedat FROM users
|
||||
ON DUPLICATE KEY UPDATE auth_version=auth_version`); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if err := bumpVersion(a, 118); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
if a.version != adpVersion {
|
||||
return errors.New("Failed to perform database upgrade to version " + strconv.Itoa(adpVersion) +
|
||||
". DB is still at " + strconv.Itoa(a.version))
|
||||
@@ -1053,6 +1149,11 @@ func (a *adapter) UserCreate(user *t.User) error {
|
||||
return err
|
||||
}
|
||||
|
||||
if _, err = tx.Exec("INSERT INTO im_user_security(tenant_id,user_id,auth_version,created_at,updated_at) VALUES(?,?,?,?,?)",
|
||||
user.TenantID, decoded_uid, 1, user.CreatedAt, user.UpdatedAt); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// Save user's tags to a separate table to make user findable.
|
||||
if err = addTenantTags(tx, user.TenantID, "usertags", "userid", decoded_uid, user.Tags, false); err != nil {
|
||||
return err
|
||||
|
||||
Reference in New Issue
Block a user