({
req,
db,
logger,
secret,
now = Date.now,
}: GetLoginStatusDeps)
| 22 | }) |
| 23 | |
| 24 | export async function getLoginStatus({ |
| 25 | req, |
| 26 | db, |
| 27 | logger, |
| 28 | secret, |
| 29 | now = Date.now, |
| 30 | }: GetLoginStatusDeps): Promise<NextResponse> { |
| 31 | const { searchParams } = new URL(req.url) |
| 32 | const result = reqSchema.safeParse({ |
| 33 | fingerprintId: searchParams.get('fingerprintId'), |
| 34 | fingerprintHash: searchParams.get('fingerprintHash'), |
| 35 | expiresAt: searchParams.get('expiresAt'), |
| 36 | }) |
| 37 | if (!result.success) { |
| 38 | return NextResponse.json( |
| 39 | { error: 'Invalid query parameters' }, |
| 40 | { status: 400 }, |
| 41 | ) |
| 42 | } |
| 43 | |
| 44 | const { fingerprintId, fingerprintHash, expiresAt } = result.data |
| 45 | |
| 46 | if (now() > expiresAt) { |
| 47 | logger.info( |
| 48 | { fingerprintId, fingerprintHash, expiresAt }, |
| 49 | 'Auth code expired', |
| 50 | ) |
| 51 | return NextResponse.json( |
| 52 | { error: 'Authentication failed' }, |
| 53 | { status: 401 }, |
| 54 | ) |
| 55 | } |
| 56 | |
| 57 | const expectedHash = genAuthCode(fingerprintId, expiresAt.toString(), secret) |
| 58 | if (fingerprintHash !== expectedHash) { |
| 59 | logger.info( |
| 60 | { fingerprintId, fingerprintHash, expectedHash }, |
| 61 | 'Invalid auth code', |
| 62 | ) |
| 63 | return NextResponse.json( |
| 64 | { error: 'Authentication failed' }, |
| 65 | { status: 401 }, |
| 66 | ) |
| 67 | } |
| 68 | |
| 69 | try { |
| 70 | const user = await db.getCliSessionForAuth(fingerprintId, fingerprintHash) |
| 71 | |
| 72 | if (!user) { |
| 73 | logger.info( |
| 74 | { fingerprintId, fingerprintHash }, |
| 75 | 'No active CLI session found for login auth code', |
| 76 | ) |
| 77 | return NextResponse.json( |
| 78 | { error: 'Authentication failed' }, |
| 79 | { status: 401 }, |
| 80 | ) |
| 81 | } |
no test coverage detected