feat: user/service sessions repo
This commit is contained in:
@ -8,6 +8,7 @@ import (
|
||||
"time"
|
||||
|
||||
"github.com/google/uuid"
|
||||
"github.com/jackc/pgx/v5/pgtype"
|
||||
)
|
||||
|
||||
type ApiService struct {
|
||||
@ -25,6 +26,24 @@ type ApiService struct {
|
||||
IconUrl *string `json:"icon_url"`
|
||||
}
|
||||
|
||||
type ServiceSession struct {
|
||||
ID uuid.UUID `json:"id"`
|
||||
ServiceID uuid.UUID `json:"service_id"`
|
||||
ClientID string `json:"client_id"`
|
||||
UserID *uuid.UUID `json:"user_id"`
|
||||
IssuedAt time.Time `json:"issued_at"`
|
||||
ExpiresAt *time.Time `json:"expires_at"`
|
||||
LastActive *time.Time `json:"last_active"`
|
||||
IpAddress pgtype.Text `json:"ip_address"`
|
||||
UserAgent *string `json:"user_agent"`
|
||||
AccessTokenID *uuid.UUID `json:"access_token_id"`
|
||||
RefreshTokenID *uuid.UUID `json:"refresh_token_id"`
|
||||
IsActive bool `json:"is_active"`
|
||||
RevokedAt *time.Time `json:"revoked_at"`
|
||||
Scope *string `json:"scope"`
|
||||
Claims []byte `json:"claims"`
|
||||
}
|
||||
|
||||
type User struct {
|
||||
ID uuid.UUID `json:"id"`
|
||||
Email string `json:"email"`
|
||||
@ -41,3 +60,19 @@ type User struct {
|
||||
AvatarVerified bool `json:"avatar_verified"`
|
||||
Verified bool `json:"verified"`
|
||||
}
|
||||
|
||||
type UserSession struct {
|
||||
ID uuid.UUID `json:"id"`
|
||||
UserID uuid.UUID `json:"user_id"`
|
||||
SessionType string `json:"session_type"`
|
||||
IssuedAt time.Time `json:"issued_at"`
|
||||
ExpiresAt *time.Time `json:"expires_at"`
|
||||
LastActive *time.Time `json:"last_active"`
|
||||
IpAddress pgtype.Text `json:"ip_address"`
|
||||
UserAgent *string `json:"user_agent"`
|
||||
AccessTokenID *uuid.UUID `json:"access_token_id"`
|
||||
RefreshTokenID *uuid.UUID `json:"refresh_token_id"`
|
||||
DeviceInfo []byte `json:"device_info"`
|
||||
IsActive bool `json:"is_active"`
|
||||
RevokedAt *time.Time `json:"revoked_at"`
|
||||
}
|
||||
|
288
internal/repository/service_sessions.sql.go
Normal file
288
internal/repository/service_sessions.sql.go
Normal file
@ -0,0 +1,288 @@
|
||||
// Code generated by sqlc. DO NOT EDIT.
|
||||
// versions:
|
||||
// sqlc v1.29.0
|
||||
// source: service_sessions.sql
|
||||
|
||||
package repository
|
||||
|
||||
import (
|
||||
"context"
|
||||
"time"
|
||||
|
||||
"github.com/google/uuid"
|
||||
"github.com/jackc/pgx/v5/pgtype"
|
||||
)
|
||||
|
||||
const createServiceSession = `-- name: CreateServiceSession :one
|
||||
INSERT INTO service_sessions (
|
||||
service_id, client_id, user_id, issued_at, expires_at, last_active,
|
||||
ip_address, user_agent, access_token_id, refresh_token_id,
|
||||
is_active, scope, claims
|
||||
) VALUES (
|
||||
$1, $2, $3, NOW(), $4, $5,
|
||||
$6, $7, $8, $9,
|
||||
TRUE, $8, $9
|
||||
)
|
||||
RETURNING id, service_id, client_id, user_id, issued_at, expires_at, last_active, ip_address, user_agent, access_token_id, refresh_token_id, is_active, revoked_at, scope, claims
|
||||
`
|
||||
|
||||
type CreateServiceSessionParams struct {
|
||||
ServiceID uuid.UUID `json:"service_id"`
|
||||
ClientID string `json:"client_id"`
|
||||
UserID *uuid.UUID `json:"user_id"`
|
||||
ExpiresAt *time.Time `json:"expires_at"`
|
||||
LastActive *time.Time `json:"last_active"`
|
||||
IpAddress pgtype.Text `json:"ip_address"`
|
||||
UserAgent *string `json:"user_agent"`
|
||||
AccessTokenID *uuid.UUID `json:"access_token_id"`
|
||||
RefreshTokenID *uuid.UUID `json:"refresh_token_id"`
|
||||
}
|
||||
|
||||
func (q *Queries) CreateServiceSession(ctx context.Context, arg CreateServiceSessionParams) (ServiceSession, error) {
|
||||
row := q.db.QueryRow(ctx, createServiceSession,
|
||||
arg.ServiceID,
|
||||
arg.ClientID,
|
||||
arg.UserID,
|
||||
arg.ExpiresAt,
|
||||
arg.LastActive,
|
||||
arg.IpAddress,
|
||||
arg.UserAgent,
|
||||
arg.AccessTokenID,
|
||||
arg.RefreshTokenID,
|
||||
)
|
||||
var i ServiceSession
|
||||
err := row.Scan(
|
||||
&i.ID,
|
||||
&i.ServiceID,
|
||||
&i.ClientID,
|
||||
&i.UserID,
|
||||
&i.IssuedAt,
|
||||
&i.ExpiresAt,
|
||||
&i.LastActive,
|
||||
&i.IpAddress,
|
||||
&i.UserAgent,
|
||||
&i.AccessTokenID,
|
||||
&i.RefreshTokenID,
|
||||
&i.IsActive,
|
||||
&i.RevokedAt,
|
||||
&i.Scope,
|
||||
&i.Claims,
|
||||
)
|
||||
return i, err
|
||||
}
|
||||
|
||||
const getServiceSessionByAccessJTI = `-- name: GetServiceSessionByAccessJTI :one
|
||||
SELECT id, service_id, client_id, user_id, issued_at, expires_at, last_active, ip_address, user_agent, access_token_id, refresh_token_id, is_active, revoked_at, scope, claims FROM service_sessions
|
||||
WHERE access_token_id = $1
|
||||
AND is_active = TRUE
|
||||
`
|
||||
|
||||
func (q *Queries) GetServiceSessionByAccessJTI(ctx context.Context, accessTokenID *uuid.UUID) (ServiceSession, error) {
|
||||
row := q.db.QueryRow(ctx, getServiceSessionByAccessJTI, accessTokenID)
|
||||
var i ServiceSession
|
||||
err := row.Scan(
|
||||
&i.ID,
|
||||
&i.ServiceID,
|
||||
&i.ClientID,
|
||||
&i.UserID,
|
||||
&i.IssuedAt,
|
||||
&i.ExpiresAt,
|
||||
&i.LastActive,
|
||||
&i.IpAddress,
|
||||
&i.UserAgent,
|
||||
&i.AccessTokenID,
|
||||
&i.RefreshTokenID,
|
||||
&i.IsActive,
|
||||
&i.RevokedAt,
|
||||
&i.Scope,
|
||||
&i.Claims,
|
||||
)
|
||||
return i, err
|
||||
}
|
||||
|
||||
const getServiceSessionByRefreshJTI = `-- name: GetServiceSessionByRefreshJTI :one
|
||||
SELECT id, service_id, client_id, user_id, issued_at, expires_at, last_active, ip_address, user_agent, access_token_id, refresh_token_id, is_active, revoked_at, scope, claims FROM service_sessions
|
||||
WHERE refresh_token_id = $1
|
||||
AND is_active = TRUE
|
||||
`
|
||||
|
||||
func (q *Queries) GetServiceSessionByRefreshJTI(ctx context.Context, refreshTokenID *uuid.UUID) (ServiceSession, error) {
|
||||
row := q.db.QueryRow(ctx, getServiceSessionByRefreshJTI, refreshTokenID)
|
||||
var i ServiceSession
|
||||
err := row.Scan(
|
||||
&i.ID,
|
||||
&i.ServiceID,
|
||||
&i.ClientID,
|
||||
&i.UserID,
|
||||
&i.IssuedAt,
|
||||
&i.ExpiresAt,
|
||||
&i.LastActive,
|
||||
&i.IpAddress,
|
||||
&i.UserAgent,
|
||||
&i.AccessTokenID,
|
||||
&i.RefreshTokenID,
|
||||
&i.IsActive,
|
||||
&i.RevokedAt,
|
||||
&i.Scope,
|
||||
&i.Claims,
|
||||
)
|
||||
return i, err
|
||||
}
|
||||
|
||||
const listActiveServiceSessionsByClient = `-- name: ListActiveServiceSessionsByClient :many
|
||||
SELECT id, service_id, client_id, user_id, issued_at, expires_at, last_active, ip_address, user_agent, access_token_id, refresh_token_id, is_active, revoked_at, scope, claims FROM service_sessions
|
||||
WHERE client_id = $1
|
||||
AND is_active = TRUE
|
||||
ORDER BY issued_at DESC
|
||||
`
|
||||
|
||||
func (q *Queries) ListActiveServiceSessionsByClient(ctx context.Context, clientID string) ([]ServiceSession, error) {
|
||||
rows, err := q.db.Query(ctx, listActiveServiceSessionsByClient, clientID)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
defer rows.Close()
|
||||
var items []ServiceSession
|
||||
for rows.Next() {
|
||||
var i ServiceSession
|
||||
if err := rows.Scan(
|
||||
&i.ID,
|
||||
&i.ServiceID,
|
||||
&i.ClientID,
|
||||
&i.UserID,
|
||||
&i.IssuedAt,
|
||||
&i.ExpiresAt,
|
||||
&i.LastActive,
|
||||
&i.IpAddress,
|
||||
&i.UserAgent,
|
||||
&i.AccessTokenID,
|
||||
&i.RefreshTokenID,
|
||||
&i.IsActive,
|
||||
&i.RevokedAt,
|
||||
&i.Scope,
|
||||
&i.Claims,
|
||||
); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
items = append(items, i)
|
||||
}
|
||||
if err := rows.Err(); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return items, nil
|
||||
}
|
||||
|
||||
const listActiveServiceSessionsByUser = `-- name: ListActiveServiceSessionsByUser :many
|
||||
SELECT id, service_id, client_id, user_id, issued_at, expires_at, last_active, ip_address, user_agent, access_token_id, refresh_token_id, is_active, revoked_at, scope, claims FROM service_sessions
|
||||
WHERE user_id = $1
|
||||
AND is_active = TRUE
|
||||
ORDER BY issued_at DESC
|
||||
`
|
||||
|
||||
func (q *Queries) ListActiveServiceSessionsByUser(ctx context.Context, userID *uuid.UUID) ([]ServiceSession, error) {
|
||||
rows, err := q.db.Query(ctx, listActiveServiceSessionsByUser, userID)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
defer rows.Close()
|
||||
var items []ServiceSession
|
||||
for rows.Next() {
|
||||
var i ServiceSession
|
||||
if err := rows.Scan(
|
||||
&i.ID,
|
||||
&i.ServiceID,
|
||||
&i.ClientID,
|
||||
&i.UserID,
|
||||
&i.IssuedAt,
|
||||
&i.ExpiresAt,
|
||||
&i.LastActive,
|
||||
&i.IpAddress,
|
||||
&i.UserAgent,
|
||||
&i.AccessTokenID,
|
||||
&i.RefreshTokenID,
|
||||
&i.IsActive,
|
||||
&i.RevokedAt,
|
||||
&i.Scope,
|
||||
&i.Claims,
|
||||
); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
items = append(items, i)
|
||||
}
|
||||
if err := rows.Err(); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return items, nil
|
||||
}
|
||||
|
||||
const listAllServiceSessions = `-- name: ListAllServiceSessions :many
|
||||
SELECT id, service_id, client_id, user_id, issued_at, expires_at, last_active, ip_address, user_agent, access_token_id, refresh_token_id, is_active, revoked_at, scope, claims FROM service_sessions
|
||||
ORDER BY issued_at DESC
|
||||
LIMIT $1 OFFSET $2
|
||||
`
|
||||
|
||||
type ListAllServiceSessionsParams struct {
|
||||
Limit int32 `json:"limit"`
|
||||
Offset int32 `json:"offset"`
|
||||
}
|
||||
|
||||
func (q *Queries) ListAllServiceSessions(ctx context.Context, arg ListAllServiceSessionsParams) ([]ServiceSession, error) {
|
||||
rows, err := q.db.Query(ctx, listAllServiceSessions, arg.Limit, arg.Offset)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
defer rows.Close()
|
||||
var items []ServiceSession
|
||||
for rows.Next() {
|
||||
var i ServiceSession
|
||||
if err := rows.Scan(
|
||||
&i.ID,
|
||||
&i.ServiceID,
|
||||
&i.ClientID,
|
||||
&i.UserID,
|
||||
&i.IssuedAt,
|
||||
&i.ExpiresAt,
|
||||
&i.LastActive,
|
||||
&i.IpAddress,
|
||||
&i.UserAgent,
|
||||
&i.AccessTokenID,
|
||||
&i.RefreshTokenID,
|
||||
&i.IsActive,
|
||||
&i.RevokedAt,
|
||||
&i.Scope,
|
||||
&i.Claims,
|
||||
); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
items = append(items, i)
|
||||
}
|
||||
if err := rows.Err(); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return items, nil
|
||||
}
|
||||
|
||||
const revokeServiceSession = `-- name: RevokeServiceSession :exec
|
||||
UPDATE service_sessions
|
||||
SET is_active = FALSE,
|
||||
revoked_at = NOW()
|
||||
WHERE id = $1
|
||||
AND is_active = TRUE
|
||||
`
|
||||
|
||||
func (q *Queries) RevokeServiceSession(ctx context.Context, id uuid.UUID) error {
|
||||
_, err := q.db.Exec(ctx, revokeServiceSession, id)
|
||||
return err
|
||||
}
|
||||
|
||||
const updateServiceSessionLastActive = `-- name: UpdateServiceSessionLastActive :exec
|
||||
UPDATE service_sessions
|
||||
SET last_active = NOW()
|
||||
WHERE id = $1
|
||||
AND is_active = TRUE
|
||||
`
|
||||
|
||||
func (q *Queries) UpdateServiceSessionLastActive(ctx context.Context, id uuid.UUID) error {
|
||||
_, err := q.db.Exec(ctx, updateServiceSessionLastActive, id)
|
||||
return err
|
||||
}
|
235
internal/repository/user_sessions.sql.go
Normal file
235
internal/repository/user_sessions.sql.go
Normal file
@ -0,0 +1,235 @@
|
||||
// Code generated by sqlc. DO NOT EDIT.
|
||||
// versions:
|
||||
// sqlc v1.29.0
|
||||
// source: user_sessions.sql
|
||||
|
||||
package repository
|
||||
|
||||
import (
|
||||
"context"
|
||||
"time"
|
||||
|
||||
"github.com/google/uuid"
|
||||
"github.com/jackc/pgx/v5/pgtype"
|
||||
)
|
||||
|
||||
const createUserSession = `-- name: CreateUserSession :one
|
||||
INSERT INTO user_sessions (
|
||||
user_id, session_type, issued_at, expires_at, last_active,
|
||||
ip_address, user_agent, access_token_id, refresh_token_id,
|
||||
device_info, is_active
|
||||
) VALUES (
|
||||
$1, $2, NOW(), $3, $4,
|
||||
$5, $6, $7, $8,
|
||||
$9, TRUE
|
||||
)
|
||||
RETURNING id, user_id, session_type, issued_at, expires_at, last_active, ip_address, user_agent, access_token_id, refresh_token_id, device_info, is_active, revoked_at
|
||||
`
|
||||
|
||||
type CreateUserSessionParams struct {
|
||||
UserID uuid.UUID `json:"user_id"`
|
||||
SessionType string `json:"session_type"`
|
||||
ExpiresAt *time.Time `json:"expires_at"`
|
||||
LastActive *time.Time `json:"last_active"`
|
||||
IpAddress pgtype.Text `json:"ip_address"`
|
||||
UserAgent *string `json:"user_agent"`
|
||||
AccessTokenID *uuid.UUID `json:"access_token_id"`
|
||||
RefreshTokenID *uuid.UUID `json:"refresh_token_id"`
|
||||
DeviceInfo []byte `json:"device_info"`
|
||||
}
|
||||
|
||||
func (q *Queries) CreateUserSession(ctx context.Context, arg CreateUserSessionParams) (UserSession, error) {
|
||||
row := q.db.QueryRow(ctx, createUserSession,
|
||||
arg.UserID,
|
||||
arg.SessionType,
|
||||
arg.ExpiresAt,
|
||||
arg.LastActive,
|
||||
arg.IpAddress,
|
||||
arg.UserAgent,
|
||||
arg.AccessTokenID,
|
||||
arg.RefreshTokenID,
|
||||
arg.DeviceInfo,
|
||||
)
|
||||
var i UserSession
|
||||
err := row.Scan(
|
||||
&i.ID,
|
||||
&i.UserID,
|
||||
&i.SessionType,
|
||||
&i.IssuedAt,
|
||||
&i.ExpiresAt,
|
||||
&i.LastActive,
|
||||
&i.IpAddress,
|
||||
&i.UserAgent,
|
||||
&i.AccessTokenID,
|
||||
&i.RefreshTokenID,
|
||||
&i.DeviceInfo,
|
||||
&i.IsActive,
|
||||
&i.RevokedAt,
|
||||
)
|
||||
return i, err
|
||||
}
|
||||
|
||||
const getUserSessionByAccessJTI = `-- name: GetUserSessionByAccessJTI :one
|
||||
SELECT id, user_id, session_type, issued_at, expires_at, last_active, ip_address, user_agent, access_token_id, refresh_token_id, device_info, is_active, revoked_at FROM user_sessions
|
||||
WHERE access_token_id = $1
|
||||
AND is_active = TRUE
|
||||
`
|
||||
|
||||
func (q *Queries) GetUserSessionByAccessJTI(ctx context.Context, accessTokenID *uuid.UUID) (UserSession, error) {
|
||||
row := q.db.QueryRow(ctx, getUserSessionByAccessJTI, accessTokenID)
|
||||
var i UserSession
|
||||
err := row.Scan(
|
||||
&i.ID,
|
||||
&i.UserID,
|
||||
&i.SessionType,
|
||||
&i.IssuedAt,
|
||||
&i.ExpiresAt,
|
||||
&i.LastActive,
|
||||
&i.IpAddress,
|
||||
&i.UserAgent,
|
||||
&i.AccessTokenID,
|
||||
&i.RefreshTokenID,
|
||||
&i.DeviceInfo,
|
||||
&i.IsActive,
|
||||
&i.RevokedAt,
|
||||
)
|
||||
return i, err
|
||||
}
|
||||
|
||||
const getUserSessionByRefreshJTI = `-- name: GetUserSessionByRefreshJTI :one
|
||||
SELECT id, user_id, session_type, issued_at, expires_at, last_active, ip_address, user_agent, access_token_id, refresh_token_id, device_info, is_active, revoked_at FROM user_sessions
|
||||
WHERE refresh_token_id = $1
|
||||
AND is_active = TRUE
|
||||
`
|
||||
|
||||
func (q *Queries) GetUserSessionByRefreshJTI(ctx context.Context, refreshTokenID *uuid.UUID) (UserSession, error) {
|
||||
row := q.db.QueryRow(ctx, getUserSessionByRefreshJTI, refreshTokenID)
|
||||
var i UserSession
|
||||
err := row.Scan(
|
||||
&i.ID,
|
||||
&i.UserID,
|
||||
&i.SessionType,
|
||||
&i.IssuedAt,
|
||||
&i.ExpiresAt,
|
||||
&i.LastActive,
|
||||
&i.IpAddress,
|
||||
&i.UserAgent,
|
||||
&i.AccessTokenID,
|
||||
&i.RefreshTokenID,
|
||||
&i.DeviceInfo,
|
||||
&i.IsActive,
|
||||
&i.RevokedAt,
|
||||
)
|
||||
return i, err
|
||||
}
|
||||
|
||||
const listActiveUserSessions = `-- name: ListActiveUserSessions :many
|
||||
SELECT id, user_id, session_type, issued_at, expires_at, last_active, ip_address, user_agent, access_token_id, refresh_token_id, device_info, is_active, revoked_at FROM user_sessions
|
||||
WHERE user_id = $1
|
||||
AND is_active = TRUE
|
||||
ORDER BY issued_at DESC
|
||||
`
|
||||
|
||||
func (q *Queries) ListActiveUserSessions(ctx context.Context, userID uuid.UUID) ([]UserSession, error) {
|
||||
rows, err := q.db.Query(ctx, listActiveUserSessions, userID)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
defer rows.Close()
|
||||
var items []UserSession
|
||||
for rows.Next() {
|
||||
var i UserSession
|
||||
if err := rows.Scan(
|
||||
&i.ID,
|
||||
&i.UserID,
|
||||
&i.SessionType,
|
||||
&i.IssuedAt,
|
||||
&i.ExpiresAt,
|
||||
&i.LastActive,
|
||||
&i.IpAddress,
|
||||
&i.UserAgent,
|
||||
&i.AccessTokenID,
|
||||
&i.RefreshTokenID,
|
||||
&i.DeviceInfo,
|
||||
&i.IsActive,
|
||||
&i.RevokedAt,
|
||||
); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
items = append(items, i)
|
||||
}
|
||||
if err := rows.Err(); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return items, nil
|
||||
}
|
||||
|
||||
const listAllSessions = `-- name: ListAllSessions :many
|
||||
SELECT id, user_id, session_type, issued_at, expires_at, last_active, ip_address, user_agent, access_token_id, refresh_token_id, device_info, is_active, revoked_at FROM user_sessions
|
||||
ORDER BY issued_at DESC
|
||||
LIMIT $1 OFFSET $2
|
||||
`
|
||||
|
||||
type ListAllSessionsParams struct {
|
||||
Limit int32 `json:"limit"`
|
||||
Offset int32 `json:"offset"`
|
||||
}
|
||||
|
||||
func (q *Queries) ListAllSessions(ctx context.Context, arg ListAllSessionsParams) ([]UserSession, error) {
|
||||
rows, err := q.db.Query(ctx, listAllSessions, arg.Limit, arg.Offset)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
defer rows.Close()
|
||||
var items []UserSession
|
||||
for rows.Next() {
|
||||
var i UserSession
|
||||
if err := rows.Scan(
|
||||
&i.ID,
|
||||
&i.UserID,
|
||||
&i.SessionType,
|
||||
&i.IssuedAt,
|
||||
&i.ExpiresAt,
|
||||
&i.LastActive,
|
||||
&i.IpAddress,
|
||||
&i.UserAgent,
|
||||
&i.AccessTokenID,
|
||||
&i.RefreshTokenID,
|
||||
&i.DeviceInfo,
|
||||
&i.IsActive,
|
||||
&i.RevokedAt,
|
||||
); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
items = append(items, i)
|
||||
}
|
||||
if err := rows.Err(); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return items, nil
|
||||
}
|
||||
|
||||
const revokeUserSession = `-- name: RevokeUserSession :exec
|
||||
UPDATE user_sessions
|
||||
SET is_active = FALSE,
|
||||
revoked_at = NOW()
|
||||
WHERE id = $1
|
||||
AND is_active = TRUE
|
||||
`
|
||||
|
||||
func (q *Queries) RevokeUserSession(ctx context.Context, id uuid.UUID) error {
|
||||
_, err := q.db.Exec(ctx, revokeUserSession, id)
|
||||
return err
|
||||
}
|
||||
|
||||
const updateSessionLastActive = `-- name: UpdateSessionLastActive :exec
|
||||
UPDATE user_sessions
|
||||
SET last_active = NOW()
|
||||
WHERE id = $1
|
||||
AND is_active = TRUE
|
||||
`
|
||||
|
||||
func (q *Queries) UpdateSessionLastActive(ctx context.Context, id uuid.UUID) error {
|
||||
_, err := q.db.Exec(ctx, updateSessionLastActive, id)
|
||||
return err
|
||||
}
|
@ -15,7 +15,8 @@ CREATE TABLE user_sessions (
|
||||
TIME ZONE,
|
||||
ip_address VARCHAR(45), -- supports IPv4/IPv6
|
||||
user_agent TEXT,
|
||||
refresh_token TEXT,
|
||||
access_token_id UUID,
|
||||
refresh_token_id UUID,
|
||||
device_info JSONB, -- optional: structured info (browser, OS, etc.)
|
||||
is_active BOOLEAN NOT NULL DEFAULT TRUE,
|
||||
revoked_at TIMESTAMP
|
||||
|
@ -16,7 +16,8 @@ CREATE TABLE service_sessions (
|
||||
TIME ZONE,
|
||||
ip_address VARCHAR(45),
|
||||
user_agent TEXT,
|
||||
refresh_token TEXT,
|
||||
access_token_id UUID,
|
||||
refresh_token_id UUID,
|
||||
is_active BOOLEAN NOT NULL DEFAULT TRUE,
|
||||
revoked_at TIMESTAMP
|
||||
WITH
|
||||
|
@ -1,10 +1,12 @@
|
||||
-- name: CreateServiceSession :one
|
||||
INSERT INTO service_sessions (
|
||||
client_id, user_id, issued_at, expires_at, last_active,
|
||||
ip_address, user_agent, is_active, scope, claims
|
||||
service_id, client_id, user_id, issued_at, expires_at, last_active,
|
||||
ip_address, user_agent, access_token_id, refresh_token_id,
|
||||
is_active, scope, claims
|
||||
) VALUES (
|
||||
$1, $2, NOW(), $3, $4,
|
||||
$5, $6, $6, TRUE, $7, $8
|
||||
$1, $2, $3, NOW(), $4, $5,
|
||||
$6, $7, $8, $9,
|
||||
TRUE, $8, $9
|
||||
)
|
||||
RETURNING *;
|
||||
|
||||
@ -20,9 +22,14 @@ WHERE user_id = $1
|
||||
AND is_active = TRUE
|
||||
ORDER BY issued_at DESC;
|
||||
|
||||
-- name: GetServiceSessionByToken :one
|
||||
-- name: GetServiceSessionByAccessJTI :one
|
||||
SELECT * FROM service_sessions
|
||||
WHERE refresh_token = $1
|
||||
WHERE access_token_id = $1
|
||||
AND is_active = TRUE;
|
||||
|
||||
-- name: GetServiceSessionByRefreshJTI :one
|
||||
SELECT * FROM service_sessions
|
||||
WHERE refresh_token_id = $1
|
||||
AND is_active = TRUE;
|
||||
|
||||
-- name: RevokeServiceSession :exec
|
||||
|
@ -1,12 +1,12 @@
|
||||
-- name: CreateUserSession :one
|
||||
INSERT INTO user_sessions (
|
||||
user_id, session_type, issued_at, expires_at, last_active,
|
||||
ip_address, user_agent,
|
||||
ip_address, user_agent, access_token_id, refresh_token_id,
|
||||
device_info, is_active
|
||||
) VALUES (
|
||||
$1, $2, NOW(), $3, $4,
|
||||
$5, $6,
|
||||
$7, TRUE
|
||||
$5, $6, $7, $8,
|
||||
$9, TRUE
|
||||
)
|
||||
RETURNING *;
|
||||
|
||||
@ -16,9 +16,14 @@ WHERE user_id = $1
|
||||
AND is_active = TRUE
|
||||
ORDER BY issued_at DESC;
|
||||
|
||||
-- name: GetUserSessionByToken :one
|
||||
-- name: GetUserSessionByAccessJTI :one
|
||||
SELECT * FROM user_sessions
|
||||
WHERE refresh_token = $1
|
||||
WHERE access_token_id = $1
|
||||
AND is_active = TRUE;
|
||||
|
||||
-- name: GetUserSessionByRefreshJTI :one
|
||||
SELECT * FROM user_sessions
|
||||
WHERE refresh_token_id = $1
|
||||
AND is_active = TRUE;
|
||||
|
||||
-- name: RevokeUserSession :exec
|
||||
|
Reference in New Issue
Block a user