46 lines
1.4 KiB
Swift
46 lines
1.4 KiB
Swift
import SQLKit
|
|
import Vapor
|
|
|
|
struct UserToken: Decodable {
|
|
let token: String
|
|
|
|
static func create (connection: any SQLDatabase) async throws -> UserToken {
|
|
return try await connection.raw ("""
|
|
SELECT string_agg (substr (c, (random() * length (c) + 1)::integer, 1), '') AS "token"
|
|
FROM (VALUES ('ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789')) AS x(c),
|
|
generate_series (1, 32)
|
|
""")
|
|
.first (decoding: UserToken.self)!
|
|
}
|
|
|
|
struct Token: Content {
|
|
let userId: UUID
|
|
let email: String
|
|
|
|
enum CodingKeys: String, CodingKey {
|
|
case userId = "user_id"
|
|
case email
|
|
}
|
|
}
|
|
|
|
static func fetch (token: String, connection: any SQLDatabase) async throws -> Token? {
|
|
return try await connection.raw ("""
|
|
SELECT "user_id", "email"
|
|
FROM "user_tokens"
|
|
JOIN "users"
|
|
ON "users"."id" = "user_tokens"."user_id"
|
|
WHERE "token" = \(bind: token)
|
|
AND "insert_time" >= CURRENT_TIMESTAMP - INTERVAL '1 HOUR'
|
|
""")
|
|
.first (decoding: Token.self)
|
|
}
|
|
|
|
static func delete (token: String, connection: any SQLDatabase) async throws {
|
|
return try await connection.raw ("""
|
|
DELETE FROM "user_tokens"
|
|
WHERE "token" = \(bind: token)
|
|
""")
|
|
.run()
|
|
}
|
|
}
|