Files
lagos-back/src/lib/oauthState.ts
T
mstfyldzandClaude Sonnet 5 328aef91bd feat: Google Drive backup OAuth (Faz 1 — backend)
PRD "AyrisLegal Google Drive Backup & Recovery" kapsamında sadece
backend altyapısı: OAuth connect/callback/status/disconnect/refresh
uç noktaları, AES-256-GCM token şifreleme (tokenCrypto.ts), tek
kullanımlık CSRF state (oauthState.ts), drive.file scope ile
AyrisLegal/Davalar klasör oluşturma (googleDriveClient.ts). Electron
tarafı (dosya tarama/kuyruk/UI) ayrı bir aşamada.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-08-10 03:51:02 +03:00

37 lines
1.4 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
import crypto from 'crypto';
// Google OAuth "state" parametresi: CSRF'e karşı kriptografik olarak rastgele,
// kısa ömürlü, tek kullanımlık (bkz. PRD §20). Bellek-içi Map yeterli — OAuth
// akışı saniyeler/dakikalar içinde tamamlanıyor, kalıcı depolamaya gerek yok.
// NOT: backend birden fazla instance'la (load balancer arkasında) çalışırsa bu
// state farklı bir instance'a düşebilir — o zaman paylaşımlı bir store (Redis
// vb.) gerekir. Şu an tek instance varsayımıyla yazıldı.
interface StateEntry { userId: string; expiresAt: number; }
const STATE_TTL_MS = 10 * 60 * 1000; // 10 dakika
const stateStore = new Map<string, StateEntry>();
function cleanupExpired() {
const now = Date.now();
for (const [key, entry] of stateStore.entries()) {
if (entry.expiresAt < now) stateStore.delete(key);
}
}
export function createState(userId: string): string {
cleanupExpired();
const state = crypto.randomBytes(32).toString('hex');
stateStore.set(state, { userId, expiresAt: Date.now() + STATE_TTL_MS });
return state;
}
// Tek kullanımlık — çağrıldığı anda store'dan siliniyor, ikinci kullanım (replay)
// her zaman null döner.
export function consumeState(state: string): string | null {
const entry = stateStore.get(state);
if (!entry) return null;
stateStore.delete(state);
if (entry.expiresAt < Date.now()) return null;
return entry.userId;
}