diff --git a/backend/internal/database/query.sql.go b/backend/internal/database/query.sql.go index dd92c37..e29fa32 100644 --- a/backend/internal/database/query.sql.go +++ b/backend/internal/database/query.sql.go @@ -12,8 +12,6 @@ import ( ) const createBannedUser = `-- name: CreateBannedUser :one - - INSERT INTO banned_users(user_id, expires_at, reason, banned_by) VALUES ( $1, $2, $3, $4) RETURNING id, user_id, date, reason, expires_at, banned_by, pardoned, pardoned_by ` @@ -25,8 +23,6 @@ type CreateBannedUserParams struct { BannedBy pgtype.Text } -// : }}} -// : Banned User Object {{{ func (q *Queries) CreateBannedUser(ctx context.Context, arg CreateBannedUserParams) (BannedUser, error) { row := q.db.QueryRow(ctx, createBannedUser, arg.UserID, @@ -49,8 +45,6 @@ func (q *Queries) CreateBannedUser(ctx context.Context, arg CreateBannedUserPara } const createConfirmationCode = `-- name: CreateConfirmationCode :one - - INSERT INTO confirmation_codes(user_id, code_type, code_hash, expires_at) VALUES ($1, $2, crypt($3, gen_salt('bf')), $4) RETURNING id, user_id, code_type, code_hash, expires_at, used, deleted ` @@ -62,8 +56,6 @@ type CreateConfirmationCodeParams struct { ExpiresAt pgtype.Timestamp } -// : }}} -// : Confirmation Code Object {{{ func (q *Queries) CreateConfirmationCode(ctx context.Context, arg CreateConfirmationCodeParams) (ConfirmationCode, error) { row := q.db.QueryRow(ctx, createConfirmationCode, arg.UserID, @@ -85,22 +77,18 @@ func (q *Queries) CreateConfirmationCode(ctx context.Context, arg CreateConfirma } const createLoginInformation = `-- name: CreateLoginInformation :one - - INSERT INTO login_informations(user_id, email, password_hash) -VALUES ($1, $2, $3) RETURNING id, user_id, email, password_hash, totp_encrypted, email_2fa_enabled, password_change_date +VALUES ( $1, $2, crypt($3, gen_salt('bf')) ) RETURNING id, user_id, email, password_hash, totp_encrypted, email_2fa_enabled, password_change_date ` type CreateLoginInformationParams struct { - UserID int64 - Email pgtype.Text - PasswordHash string + UserID int64 + Email pgtype.Text + Crypt string } -// : }}} -// : Login Information Object {{{ func (q *Queries) CreateLoginInformation(ctx context.Context, arg CreateLoginInformationParams) (LoginInformation, error) { - row := q.db.QueryRow(ctx, createLoginInformation, arg.UserID, arg.Email, arg.PasswordHash) + row := q.db.QueryRow(ctx, createLoginInformation, arg.UserID, arg.Email, arg.Crypt) var i LoginInformation err := row.Scan( &i.ID, @@ -115,8 +103,6 @@ func (q *Queries) CreateLoginInformation(ctx context.Context, arg CreateLoginInf } const createProfile = `-- name: CreateProfile :one - - INSERT INTO profiles(user_id, name, bio, birthday, avatar_url, color, color_grad) VALUES ($1, $2, $3, $4, $5, $6, $7) RETURNING id, user_id, name, bio, avatar_url, birthday, color, color_grad ` @@ -131,8 +117,6 @@ type CreateProfileParams struct { ColorGrad pgtype.Text } -// }}} -// : Profile Object {{{ func (q *Queries) CreateProfile(ctx context.Context, arg CreateProfileParams) (Profile, error) { row := q.db.QueryRow(ctx, createProfile, arg.UserID, @@ -158,14 +142,10 @@ func (q *Queries) CreateProfile(ctx context.Context, arg CreateProfileParams) (P } const createProfileSettings = `-- name: CreateProfileSettings :one - - INSERT INTO profile_settings(profile_id) VALUES ($1) RETURNING id, profile_id, hide_fulfilled, hide_profile_details, hide_for_unauthenticated, hide_birthday, hide_dates, captcha, followers_only_interaction ` -// : }}} -// : Profile Settings Object {{{ func (q *Queries) CreateProfileSettings(ctx context.Context, profileID int64) (ProfileSetting, error) { row := q.db.QueryRow(ctx, createProfileSettings, profileID) var i ProfileSetting @@ -184,8 +164,6 @@ func (q *Queries) CreateProfileSettings(ctx context.Context, profileID int64) (P } const createSession = `-- name: CreateSession :one - - INSERT INTO sessions(user_id, name, platform, latest_ip) VALUES ($1, $2, $3, $4) RETURNING id, user_id, guid, name, platform, latest_ip, login_time, last_seen_date, terminated ` @@ -197,8 +175,6 @@ type CreateSessionParams struct { LatestIp pgtype.Text } -// : }}} -// Session Object {{{ func (q *Queries) CreateSession(ctx context.Context, arg CreateSessionParams) (Session, error) { row := q.db.QueryRow(ctx, createSession, arg.UserID, @@ -222,14 +198,10 @@ func (q *Queries) CreateSession(ctx context.Context, arg CreateSessionParams) (S } const createUser = `-- name: CreateUser :one - - INSERT INTO users(username, verified) VALUES ($1, false) RETURNING id, username, verified, registration_date, deleted ` -// vim:fileencoding=utf-8:foldmethod=marker -// : User Object {{{ func (q *Queries) CreateUser(ctx context.Context, username string) (User, error) { row := q.db.QueryRow(ctx, createUser, username) var i User @@ -560,6 +532,47 @@ func (q *Queries) GetUserBansByUsername(ctx context.Context, username string) ([ return items, nil } +const getUserByLoginCredentials = `-- name: GetUserByLoginCredentials :one +SELECT + users.id, + users.username, + linfo.password_hash, + linfo.totp_encrypted +FROM users +JOIN login_informations AS linfo ON users.id = linfo.user_id +LEFT JOIN banned_users AS banned ON users.id = banned.user_id +WHERE + users.username = $1 AND + users.verified IS TRUE AND -- Verified + users.deleted IS FALSE AND -- Not deleted + banned.user_id IS NULL AND -- Not banned + linfo.password_hash = crypt($2, linfo.password_hash) +` + +type GetUserByLoginCredentialsParams struct { + Username string + Crypt string +} + +type GetUserByLoginCredentialsRow struct { + ID int64 + Username string + PasswordHash string + TotpEncrypted pgtype.Text +} + +func (q *Queries) GetUserByLoginCredentials(ctx context.Context, arg GetUserByLoginCredentialsParams) (GetUserByLoginCredentialsRow, error) { + row := q.db.QueryRow(ctx, getUserByLoginCredentials, arg.Username, arg.Crypt) + var i GetUserByLoginCredentialsRow + err := row.Scan( + &i.ID, + &i.Username, + &i.PasswordHash, + &i.TotpEncrypted, + ) + return i, err +} + const getUserByUsername = `-- name: GetUserByUsername :one SELECT id, username, verified, registration_date, deleted FROM users WHERE username = $1 @@ -679,7 +692,7 @@ func (q *Queries) UpdateConfirmationCode(ctx context.Context, arg UpdateConfirma const updateLoginInformationByUsername = `-- name: UpdateLoginInformationByUsername :exec UPDATE login_informations -SET email = $2, password_hash = $3, totp_encrypted = $4, email_2fa_enabled = $5, password_change_date = $6 +SET email = $2, password_hash = crypt($3, gen_salt('bf')), totp_encrypted = $4, email_2fa_enabled = $5, password_change_date = $6 FROM users WHERE users.username = $1 AND login_informations.user_id = users.id ` @@ -687,7 +700,7 @@ WHERE users.username = $1 AND login_informations.user_id = users.id type UpdateLoginInformationByUsernameParams struct { Username string Email pgtype.Text - PasswordHash string + Crypt string TotpEncrypted pgtype.Text Email2faEnabled pgtype.Bool PasswordChangeDate pgtype.Timestamp @@ -697,7 +710,7 @@ func (q *Queries) UpdateLoginInformationByUsername(ctx context.Context, arg Upda _, err := q.db.Exec(ctx, updateLoginInformationByUsername, arg.Username, arg.Email, - arg.PasswordHash, + arg.Crypt, arg.TotpEncrypted, arg.Email2faEnabled, arg.PasswordChangeDate, diff --git a/sqlc/query.sql b/sqlc/query.sql index d7f4b35..a22625b 100644 --- a/sqlc/query.sql +++ b/sqlc/query.sql @@ -2,54 +2,70 @@ --: User Object {{{ --- name: CreateUser :one +;-- name: CreateUser :one INSERT INTO users(username, verified) VALUES ($1, false) RETURNING *; --- name: UpdateUser :exec +;-- name: UpdateUser :exec UPDATE users SET verified = $2, deleted = $3 WHERE id = $1; --- name: UpdateUserByUsername :exec +;-- name: UpdateUserByUsername :exec UPDATE users SET verified = $2, deleted = $3 WHERE username = $1; --- name: DeleteUser :exec +;-- name: DeleteUser :exec DELETE FROM users WHERE id = $1; --- name: DeleteUserByUsername :exec +;-- name: DeleteUserByUsername :exec DELETE FROM users WHERE username = $1; --- name: GetUser :one +;-- name: GetUser :one SELECT * FROM users WHERE id = $1; --- name: GetUserByUsername :one +;-- name: GetUserByUsername :one SELECT * FROM users WHERE username = $1; +;-- name: GetUserByLoginCredentials :one +SELECT + users.id, + users.username, + linfo.password_hash, + linfo.totp_encrypted +FROM users +JOIN login_informations AS linfo ON users.id = linfo.user_id +LEFT JOIN banned_users AS banned ON users.id = banned.user_id +WHERE + users.username = $1 AND + users.verified IS TRUE AND -- Verified + users.deleted IS FALSE AND -- Not deleted + banned.user_id IS NULL AND -- Not banned + linfo.password_hash = crypt($2, linfo.password_hash); -- Password hash matches + --: }}} --: Banned User Object {{{ --- name: CreateBannedUser :one +;-- name: CreateBannedUser :one INSERT INTO banned_users(user_id, expires_at, reason, banned_by) VALUES ( $1, $2, $3, $4) RETURNING *; --- name: UpdateBannedUser :exec +;-- name: UpdateBannedUser :exec UPDATE banned_users SET reason = $2, expires_at = $3, banned_by = $4, pardoned = $5, pardoned_by = $6 WHERE id = $1; --- name: GetUserBans :many +;-- name: GetUserBans :many SELECT * FROM banned_users WHERE user_id = $1; --- name: GetUserBansByUsername :many +;-- name: GetUserBansByUsername :many SELECT banned_users.* FROM banned_users JOIN users ON users.id = banned_users.user_id WHERE users.username = $1; @@ -58,17 +74,17 @@ WHERE users.username = $1; --: Login Information Object {{{ --- name: CreateLoginInformation :one +;-- name: CreateLoginInformation :one INSERT INTO login_informations(user_id, email, password_hash) -VALUES ($1, $2, $3) RETURNING *; +VALUES ( $1, $2, crypt($3, gen_salt('bf')) ) RETURNING *; --- name: UpdateLoginInformationByUsername :exec +;-- name: UpdateLoginInformationByUsername :exec UPDATE login_informations -SET email = $2, password_hash = $3, totp_encrypted = $4, email_2fa_enabled = $5, password_change_date = $6 +SET email = $2, password_hash = crypt($3, gen_salt('bf')), totp_encrypted = $4, email_2fa_enabled = $5, password_change_date = $6 FROM users WHERE users.username = $1 AND login_informations.user_id = users.id; --- name: GetLoginInformationByUsername :one +;-- name: GetLoginInformationByUsername :one SELECT login_informations.* FROM login_informations JOIN users ON users.id = login_informations.user_id WHERE users.username = $1; @@ -77,20 +93,20 @@ WHERE users.username = $1; --: Confirmation Code Object {{{ --- name: CreateConfirmationCode :one +;-- name: CreateConfirmationCode :one INSERT INTO confirmation_codes(user_id, code_type, code_hash, expires_at) VALUES ($1, $2, crypt($3, gen_salt('bf')), $4) RETURNING *; --- name: GetConfirmationCodeByCode :one +;-- name: GetConfirmationCodeByCode :one SELECT * FROM confirmation_codes WHERE user_id = $1 AND code_type = $2 AND expires_at > CURRENT_TIMESTAMP AND code_hash = crypt($3, code_hash); --- name: UpdateConfirmationCode :exec +;-- name: UpdateConfirmationCode :exec UPDATE confirmation_codes SET used = $2, deleted = $3 WHERE id = $1; --- name: PruneExpiredConfirmationCodes :exec +;-- name: PruneExpiredConfirmationCodes :exec DELETE FROM confirmation_codes WHERE expires_at < CURRENT_TIMESTAMP; @@ -98,20 +114,20 @@ WHERE expires_at < CURRENT_TIMESTAMP; -- Session Object {{{ --- name: CreateSession :one +;-- name: CreateSession :one INSERT INTO sessions(user_id, name, platform, latest_ip) VALUES ($1, $2, $3, $4) RETURNING *; --- name: UpdateSession :exec +;-- name: UpdateSession :exec UPDATE sessions SET name = $2, platform = $3, latest_ip = $4, login_time = $5, last_seen_date = $6, terminated = $7 WHERE id = $1; --- name: GetUserSessions :many +;-- name: GetUserSessions :many SELECT * FROM sessions WHERE user_id = $1 AND terminated IS FALSE; --- name: PruneTerminatedSessions :exec +;-- name: PruneTerminatedSessions :exec DELETE FROM sessions WHERE terminated IS TRUE; @@ -119,22 +135,22 @@ WHERE terminated IS TRUE; --: Profile Object {{{ --- name: CreateProfile :one +;-- name: CreateProfile :one INSERT INTO profiles(user_id, name, bio, birthday, avatar_url, color, color_grad) VALUES ($1, $2, $3, $4, $5, $6, $7) RETURNING *; --- name: UpdateProfileByUsername :exec +;-- name: UpdateProfileByUsername :exec UPDATE profiles SET name = $2, bio = $3, birthday = $4, avatar_url = $5, color = $6, color_grad = $7 FROM users WHERE username = $1; --- name: GetProfileByUsername :one +;-- name: GetProfileByUsername :one SELECT profiles.* FROM profiles JOIN users ON users.id = profiles.user_id WHERE users.username = $1; --- name: GetProfileByUsernameRestricted :one +;-- name: GetProfileByUsernameRestricted :one SELECT users.username, profiles.name, @@ -158,7 +174,7 @@ JOIN users ON users.id = profiles.user_id JOIN profile_settings ON profiles.id = profile_settings.profile_id WHERE users.username = $1 AND ($2 IS FALSE OR profile_settings.hide_for_unauthenticated IS FALSE); --- name: GetProfilesRestricted :many +;-- name: GetProfilesRestricted :many SELECT users.username, profiles.name, @@ -180,11 +196,11 @@ LIMIT 20 OFFSET 20 * $1; --: Profile Settings Object {{{ --- name: CreateProfileSettings :one +;-- name: CreateProfileSettings :one INSERT INTO profile_settings(profile_id) VALUES ($1) RETURNING *; --- name: UpdateProfileSettings :exec +;-- name: UpdateProfileSettings :exec UPDATE profile_settings SET hide_fulfilled = $2, @@ -196,7 +212,7 @@ SET followers_only_interaction = $8 WHERE id = $1; --- name: GetProfileSettingsByUsername :one +;-- name: GetProfileSettingsByUsername :one SELECT profile_settings.* FROM profile_settings JOIN profiles ON profiles.id = profile_settings.profile_id JOIN users ON users.id = profiles.user_id diff --git a/sqlc/sqlc.yaml b/sqlc/sqlc.yaml index 6e86d76..01e204f 100644 --- a/sqlc/sqlc.yaml +++ b/sqlc/sqlc.yaml @@ -9,6 +9,6 @@ sql: sql_package: "pgx/v5" database: # managed: true - uri: "postgresql://postgres:postgres@localhost:5432/mydb?sslmode=disable" + uri: "postgresql://postgres:postgres@localhost:5432/postgres?sslmode=disable" rules: - sqlc/db-prepare