init
This commit is contained in:
33
lib/crypto.ts
Normal file
33
lib/crypto.ts
Normal file
@@ -0,0 +1,33 @@
|
||||
import { createCipheriv, createDecipheriv, randomBytes } from "crypto";
|
||||
|
||||
const ALGORITHM = "aes-256-gcm";
|
||||
const IV_BYTES = 12;
|
||||
const TAG_BYTES = 16;
|
||||
|
||||
function getKey(): Buffer {
|
||||
const hex = process.env.GARMIN_ENCRYPTION_KEY;
|
||||
if (!hex || hex.length !== 64) {
|
||||
throw new Error("Brak lub nieprawidłowy GARMIN_ENCRYPTION_KEY w konfiguracji.");
|
||||
}
|
||||
return Buffer.from(hex, "hex");
|
||||
}
|
||||
|
||||
export function encrypt(plaintext: string): string {
|
||||
const key = getKey();
|
||||
const iv = randomBytes(IV_BYTES);
|
||||
const cipher = createCipheriv(ALGORITHM, key, iv);
|
||||
const encrypted = Buffer.concat([cipher.update(plaintext, "utf8"), cipher.final()]);
|
||||
const tag = cipher.getAuthTag();
|
||||
// Format: iv(hex):tag(hex):ciphertext(hex)
|
||||
return `${iv.toString("hex")}:${tag.toString("hex")}:${encrypted.toString("hex")}`;
|
||||
}
|
||||
|
||||
export function decrypt(stored: string): string {
|
||||
const parts = stored.split(":");
|
||||
if (parts.length !== 3) throw new Error("Nieprawidłowy format zaszyfrowanego hasła.");
|
||||
const [ivHex, tagHex, dataHex] = parts;
|
||||
const key = getKey();
|
||||
const decipher = createDecipheriv(ALGORITHM, key, Buffer.from(ivHex, "hex"));
|
||||
decipher.setAuthTag(Buffer.from(tagHex, "hex"));
|
||||
return decipher.update(Buffer.from(dataHex, "hex")).toString("utf8") + decipher.final("utf8");
|
||||
}
|
||||
@@ -1,5 +1,6 @@
|
||||
import type { IOauth1Token } from "garmin-connect/dist/garmin/types";
|
||||
import { getDb } from "@/lib/db";
|
||||
import { encrypt, decrypt } from "@/lib/crypto";
|
||||
import type { GarminPendingMfa } from "@/lib/garmin/sso";
|
||||
|
||||
const AUTH_COLLECTION = "garmin_auth";
|
||||
@@ -49,7 +50,7 @@ export async function getGarminCredentials(
|
||||
.collection<GarminCredentialsDoc>(CREDENTIALS_COLLECTION)
|
||||
.findOne({ _id: userId });
|
||||
if (!doc) return null;
|
||||
return { email: doc.email, password: doc.password };
|
||||
return { email: doc.email, password: decrypt(doc.password) };
|
||||
}
|
||||
|
||||
export async function saveGarminCredentials(
|
||||
@@ -60,5 +61,5 @@ export async function saveGarminCredentials(
|
||||
const db = await getDb();
|
||||
await db
|
||||
.collection<GarminCredentialsDoc>(CREDENTIALS_COLLECTION)
|
||||
.updateOne({ _id: userId }, { $set: { email, password } }, { upsert: true });
|
||||
.updateOne({ _id: userId }, { $set: { email, password: encrypt(password) } }, { upsert: true });
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user