85 lines
1.8 KiB
TypeScript
Raw Normal View History

import Database from "better-sqlite3"
import { type OAuthTokenResponse } from "@/bank/sparebank1.ts"
import dayjs, { type Dayjs } from "dayjs"
export type TokenResponse = {
key: TokenKey
token: string
expires_at: Dayjs
}
export type TokenResponseRaw = {
key: TokenResponse["key"]
token: TokenResponse["token"]
expires_at: string
}
export type TokenKey = "access-token" | "refresh-token"
export function createDb(filename: string) {
const db = new Database(filename)
db.pragma("journal_mode = WAL")
db.exec(
"CREATE TABLE IF NOT EXISTS tokens ('key' VARCHAR PRIMARY KEY, token VARCHAR NOT NULL, expires_at DATETIME NOT NULL)",
)
return db
}
export function insertTokens(
db: Database.Database,
oAuthToken: OAuthTokenResponse,
): void {
insertAccessToken(db, oAuthToken.access_token, oAuthToken.expires_in)
insertRefreshToken(
db,
oAuthToken.refresh_token,
oAuthToken.refresh_token_absolute_expires_in,
)
}
function insertAccessToken(
db: Database.Database,
accessToken: string,
expiresIn: number,
) {
insert(db, "access-token", accessToken, expiresIn)
}
function insertRefreshToken(
db: Database.Database,
refreshToken: string,
expiresIn: number,
) {
insert(db, "refresh-token", refreshToken, expiresIn)
}
function insert(
db: Database.Database,
key: TokenKey,
token: string,
expiresIn: number,
) {
db.prepare("INSERT OR REPLACE INTO tokens VALUES (?, ?, ?)").run(
key,
token,
dayjs().add(expiresIn, "seconds").toISOString(),
)
}
export function fetchToken(
db: Database.Database,
tokenKey: TokenKey,
): TokenResponse | null {
const response = db
.prepare("SELECT * FROM tokens WHERE key = ?")
.get(tokenKey) as TokenResponseRaw | null
return (
response && {
...response,
expires_at: dayjs(response.expires_at),
}
)
}