2026-06-16 09:43:48 +02:00
|
|
|
import type { IOauth1Token } from "garmin-connect/dist/garmin/types";
|
|
|
|
|
import { getDb } from "@/lib/db";
|
2026-06-18 11:12:12 +02:00
|
|
|
import { encrypt, decrypt } from "@/lib/crypto";
|
2026-06-16 09:43:48 +02:00
|
|
|
import type { GarminPendingMfa } from "@/lib/garmin/sso";
|
|
|
|
|
|
|
|
|
|
const AUTH_COLLECTION = "garmin_auth";
|
|
|
|
|
const PENDING_COLLECTION = "garmin_login_pending";
|
2026-06-18 11:02:31 +02:00
|
|
|
const CREDENTIALS_COLLECTION = "garmin_credentials";
|
2026-06-16 09:43:48 +02:00
|
|
|
|
2026-06-18 11:02:31 +02:00
|
|
|
type GarminAuthDoc = { _id: string; oauth1Token: IOauth1Token; updatedAt: Date };
|
|
|
|
|
type GarminPendingDoc = { _id: string; state: GarminPendingMfa; createdAt: Date };
|
|
|
|
|
type GarminCredentialsDoc = { _id: string; email: string; password: string };
|
2026-06-16 09:43:48 +02:00
|
|
|
|
2026-06-18 11:02:31 +02:00
|
|
|
export async function getSavedOauth1Token(userId: string): Promise<IOauth1Token | null> {
|
2026-06-16 09:43:48 +02:00
|
|
|
const db = await getDb();
|
2026-06-18 11:02:31 +02:00
|
|
|
const doc = await db.collection<GarminAuthDoc>(AUTH_COLLECTION).findOne({ _id: userId });
|
2026-06-16 09:43:48 +02:00
|
|
|
return doc?.oauth1Token ?? null;
|
|
|
|
|
}
|
|
|
|
|
|
2026-06-18 11:02:31 +02:00
|
|
|
export async function saveOauth1Token(userId: string, oauth1Token: IOauth1Token): Promise<void> {
|
2026-06-16 09:43:48 +02:00
|
|
|
const db = await getDb();
|
|
|
|
|
await db
|
|
|
|
|
.collection<GarminAuthDoc>(AUTH_COLLECTION)
|
2026-06-18 11:02:31 +02:00
|
|
|
.updateOne({ _id: userId }, { $set: { oauth1Token, updatedAt: new Date() } }, { upsert: true });
|
2026-06-16 09:43:48 +02:00
|
|
|
}
|
|
|
|
|
|
2026-06-18 11:02:31 +02:00
|
|
|
export async function savePendingMfaState(userId: string, state: GarminPendingMfa): Promise<void> {
|
2026-06-16 09:43:48 +02:00
|
|
|
const db = await getDb();
|
|
|
|
|
await db
|
|
|
|
|
.collection<GarminPendingDoc>(PENDING_COLLECTION)
|
2026-06-18 11:02:31 +02:00
|
|
|
.updateOne({ _id: userId }, { $set: { state, createdAt: new Date() } }, { upsert: true });
|
2026-06-16 09:43:48 +02:00
|
|
|
}
|
|
|
|
|
|
2026-06-18 11:02:31 +02:00
|
|
|
export async function getPendingMfaState(userId: string): Promise<GarminPendingMfa | null> {
|
2026-06-16 09:43:48 +02:00
|
|
|
const db = await getDb();
|
2026-06-18 11:02:31 +02:00
|
|
|
const doc = await db.collection<GarminPendingDoc>(PENDING_COLLECTION).findOne({ _id: userId });
|
2026-06-16 09:43:48 +02:00
|
|
|
return doc?.state ?? null;
|
|
|
|
|
}
|
|
|
|
|
|
2026-06-18 11:02:31 +02:00
|
|
|
export async function clearPendingMfaState(userId: string): Promise<void> {
|
2026-06-16 09:43:48 +02:00
|
|
|
const db = await getDb();
|
2026-06-18 11:02:31 +02:00
|
|
|
await db.collection<GarminPendingDoc>(PENDING_COLLECTION).deleteOne({ _id: userId });
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
export async function getGarminCredentials(
|
|
|
|
|
userId: string
|
|
|
|
|
): Promise<{ email: string; password: string } | null> {
|
|
|
|
|
const db = await getDb();
|
|
|
|
|
const doc = await db
|
|
|
|
|
.collection<GarminCredentialsDoc>(CREDENTIALS_COLLECTION)
|
|
|
|
|
.findOne({ _id: userId });
|
|
|
|
|
if (!doc) return null;
|
2026-06-18 11:12:12 +02:00
|
|
|
return { email: doc.email, password: decrypt(doc.password) };
|
2026-06-18 11:02:31 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
export async function saveGarminCredentials(
|
|
|
|
|
userId: string,
|
|
|
|
|
email: string,
|
|
|
|
|
password: string
|
|
|
|
|
): Promise<void> {
|
|
|
|
|
const db = await getDb();
|
|
|
|
|
await db
|
|
|
|
|
.collection<GarminCredentialsDoc>(CREDENTIALS_COLLECTION)
|
2026-06-18 11:12:12 +02:00
|
|
|
.updateOne({ _id: userId }, { $set: { email, password: encrypt(password) } }, { upsert: true });
|
2026-06-16 09:43:48 +02:00
|
|
|
}
|