Nội dung bài viết
Video học lập trình mỗi ngày
File sqlc và goose dành cho các Lập trình viên Go Member có thể lấy tại đây, Section Go 35: Code + SQL - Build Service Two Factor Authentication - Interface vs SQLC
Xem thêm: Go Backend - Hệ thống bán vé trực truyến step 1 - 34
Cách thực hiện tự động
Các thao tác auto code hệ thống xem tại đây: Build Service Two Factor Authentication - Interface vs SQLC
goose: table user_two_factor mysql
-- +goose Up
-- +goose StatementBegin
CREATE TABLE IF NOT EXISTS `pre_go_acc_user_two_factor_9999` (
`two_factor_id` INT UNSIGNED AUTO_INCREMENT PRIMARY KEY, -- Khóa chính tự động tăng
`user_id` INT UNSIGNED NOT NULL, -- Khóa ngoại liên kết tới bảng người dùng
`two_factor_auth_type` ENUM('SMS', 'EMAIL', 'APP') NOT NULL, -- Loại phương thức 2FA (SMS, Email, Ứng dụng như Google Authenticator)
`two_factor_auth_secret` VARCHAR(255) NOT NULL, -- Thông tin bí mật cho 2FA (ví dụ: mã bí mật TOTP cho ứng dụng 2FA)
`two_factor_phone` VARCHAR(20) NULL, -- Số điện thoại cho 2FA qua SMS (nếu áp dụng)
`two_factor_email` VARCHAR(255) NULL, -- Địa chỉ email cho 2FA qua Email (nếu áp dụng)
`two_factor_is_active` BOOLEAN NOT NULL DEFAULT TRUE, -- Trạng thái kích hoạt của phương thức 2FA
`two_factor_created_at` TIMESTAMP DEFAULT CURRENT_TIMESTAMP, -- Thời điểm tạo phương thức 2FA
`two_factor_updated_at` TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, -- Thời điểm cập nhật phương thức 2FA
-- Ràng buộc khóa ngoại
-- FOREIGN KEY (`user_id`) REFERENCES `pre_go_acc_user_base_9999`(`user_id`) ON DELETE CASCADE,
-- Chỉ mục để tối ưu hóa truy vấn theo `user_id` và `auth_type`
INDEX `idx_user_id` (`user_id`),
INDEX `idx_auth_type` (`two_factor_auth_type`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='pre_go_acc_user_two_factor_9999';
-- +goose StatementEnd
-- +goose Down
-- +goose StatementBegin
DROP TABLE IF EXISTS `pre_go_acc_user_two_factor_9999`;
-- +goose StatementEnd
File: Sqlc - pre_go_acc_user_two_factor.sql
-- file: pre_go_acc_user_two_factor.sql
-- EnableTwoFactor
-- name: EnableTwoFactorTypeEmail :exec
INSERT INTO pre_go_acc_user_two_factor_9999 (user_id, two_factor_auth_type, two_factor_email, two_factor_auth_secret, two_factor_is_active, two_factor_created_at, two_factor_updated_at)
VALUES (?, ?, ?, "OTP", FALSE, NOW(), NOW());
-- DisableTwoFactor
-- name: DisableTwoFactor :exec
UPDATE pre_go_acc_user_two_factor_9999
SET two_factor_is_active = FALSE,
two_factor_updated_at = NOW()
WHERE user_id = ? AND two_factor_auth_type = ?;
-- UpdateTwoFactorStatusVerification
-- name: UpdateTwoFactorStatus :exec
UPDATE pre_go_acc_user_two_factor_9999
SET two_factor_is_active = TRUE, two_factor_updated_at = NOW()
WHERE user_id = ? AND two_factor_auth_type = ? AND two_factor_is_active = FALSE;
-- VerifyTwoFactor
-- name: VerifyTwoFactor :one
SELECT COUNT(*)
FROM pre_go_acc_user_two_factor_9999
WHERE user_id = ? AND two_factor_auth_type = ? AND two_factor_is_active = TRUE;
-- GetTwoFactorStatus
-- name: GetTwoFactorStatus :one
SELECT two_factor_is_active
FROM pre_go_acc_user_two_factor_9999
WHERE user_id = ? AND two_factor_auth_type = ?;
-- IsTwoFactorEnabled
-- name: IsTwoFactorEnabled :one
SELECT COUNT(*)
FROM pre_go_acc_user_two_factor_9999
WHERE user_id = ? AND two_factor_is_active = TRUE;
-- AddOrUpdatePhoneNumber
-- name: AddOrUpdatePhoneNumber :exec
INSERT INTO pre_go_acc_user_two_factor_9999 (user_id, two_factor_phone, two_factor_is_active)
VALUES (?, ?, TRUE)
ON DUPLICATE KEY UPDATE
two_factor_phone = ?,
two_factor_updated_at = NOW();
-- AddOrUpdateEmail
-- name: AddOrUpdateEmail :exec
INSERT INTO pre_go_acc_user_two_factor_9999 (user_id, two_factor_email, two_factor_is_active)
VALUES (?, ?, TRUE)
ON DUPLICATE KEY UPDATE
two_factor_email = ?,
two_factor_updated_at = NOW();
-- GetUserTwoFactorMethods
-- name: GetUserTwoFactorMethods :many
SELECT two_factor_id, user_id, two_factor_auth_type, two_factor_auth_secret,
two_factor_phone, two_factor_email,
two_factor_is_active, two_factor_created_at, two_factor_updated_at
FROM pre_go_acc_user_two_factor_9999
WHERE user_id = ?;
-- ReactivateTwoFactor
-- name: ReactivateTwoFactor :exec
UPDATE pre_go_acc_user_two_factor_9999
SET two_factor_is_active = TRUE,
two_factor_updated_at = NOW()
WHERE user_id = ? AND two_factor_auth_type = ?;
-- RemoveTwoFactor
-- name: RemoveTwoFactor :exec
DELETE FROM pre_go_acc_user_two_factor_9999
WHERE user_id = ? AND two_factor_auth_type = ?;
-- CountActiveTwoFactorMethods
-- name: CountActiveTwoFactorMethods :one
SELECT COUNT(*)
FROM pre_go_acc_user_two_factor_9999
WHERE user_id = ? AND two_factor_is_active = TRUE;
-- GetTwoFactorMethodByID
-- name: GetTwoFactorMethodByID :one
SELECT two_factor_id, user_id, two_factor_auth_type, two_factor_auth_secret,
two_factor_phone, two_factor_email,
two_factor_is_active, two_factor_created_at, two_factor_updated_at
FROM pre_go_acc_user_two_factor_9999
WHERE two_factor_id = ?;
-- GetTwoFactorMethodByIDAndType: select lay email de sen otp
-- name: GetTwoFactorMethodByIDAndType :one
SELECT two_factor_id, user_id, two_factor_auth_type, two_factor_auth_secret,
two_factor_phone, two_factor_email,
two_factor_is_active, two_factor_created_at, two_factor_updated_at
FROM pre_go_acc_user_two_factor_9999
WHERE user_id = ? AND two_factor_auth_type = ?;