feat: add supportsv2

This commit is contained in:
Steve Korshakov 2025-09-10 20:03:57 -07:00
parent ae583ffaff
commit e961407993
3 changed files with 52 additions and 11 deletions

View File

@ -0,0 +1,2 @@
-- AlterTable
ALTER TABLE "TerminalAuthRequest" ADD COLUMN "supportsV2" BOOLEAN NOT NULL DEFAULT false;

View File

@ -49,6 +49,7 @@ model Account {
model TerminalAuthRequest { model TerminalAuthRequest {
id String @id @default(cuid()) id String @id @default(cuid())
publicKey String @unique publicKey String @unique
supportsV2 Boolean @default(false)
response String? response String?
responseAccountId String? responseAccountId String?
responseAccount Account? @relation(fields: [responseAccountId], references: [id]) responseAccount Account? @relation(fields: [responseAccountId], references: [id])
@ -227,16 +228,16 @@ model UploadedFile {
} }
model ServiceAccountToken { model ServiceAccountToken {
id String @id @default(cuid()) id String @id @default(cuid())
accountId String accountId String
account Account @relation(fields: [accountId], references: [id], onDelete: Cascade) account Account @relation(fields: [accountId], references: [id], onDelete: Cascade)
vendor String vendor String
token Bytes // Encrypted token token Bytes // Encrypted token
metadata Json? // Optional vendor metadata metadata Json? // Optional vendor metadata
lastUsedAt DateTime? lastUsedAt DateTime?
createdAt DateTime @default(now()) createdAt DateTime @default(now())
updatedAt DateTime @updatedAt updatedAt DateTime @updatedAt
@@unique([accountId, vendor]) @@unique([accountId, vendor])
@@index([accountId]) @@index([accountId])
} }

View File

@ -42,6 +42,7 @@ export function authRoutes(app: Fastify) {
schema: { schema: {
body: z.object({ body: z.object({
publicKey: z.string(), publicKey: z.string(),
supportsV2: z.boolean().nullish()
}), }),
response: { response: {
200: z.union([z.object({ 200: z.union([z.object({
@ -70,7 +71,7 @@ export function authRoutes(app: Fastify) {
const answer = await db.terminalAuthRequest.upsert({ const answer = await db.terminalAuthRequest.upsert({
where: { publicKey: publicKeyHex }, where: { publicKey: publicKeyHex },
update: {}, update: {},
create: { publicKey: publicKeyHex } create: { publicKey: publicKeyHex, supportsV2: request.body.supportsV2 ?? false }
}); });
if (answer.response && answer.responseAccountId) { if (answer.response && answer.responseAccountId) {
@ -85,6 +86,43 @@ export function authRoutes(app: Fastify) {
return reply.send({ state: 'requested' }); return reply.send({ state: 'requested' });
}); });
// Get auth request status
app.get('/v1/auth/request/status', {
schema: {
querystring: z.object({
publicKey: z.string(),
}),
response: {
200: z.object({
status: z.enum(['not_found', 'pending', 'authorized']),
supportsV2: z.boolean()
})
}
}
}, async (request, reply) => {
const tweetnacl = (await import("tweetnacl")).default;
const publicKey = privacyKit.decodeBase64(request.query.publicKey);
const isValid = tweetnacl.box.publicKeyLength === publicKey.length;
if (!isValid) {
return reply.send({ status: 'not_found', supportsV2: false });
}
const publicKeyHex = privacyKit.encodeHex(publicKey);
const authRequest = await db.terminalAuthRequest.findUnique({
where: { publicKey: publicKeyHex }
});
if (!authRequest) {
return reply.send({ status: 'not_found', supportsV2: false });
}
if (authRequest.response && authRequest.responseAccountId) {
return reply.send({ status: 'authorized', supportsV2: false });
}
return reply.send({ status: 'pending', supportsV2: authRequest.supportsV2 });
});
// Approve auth request // Approve auth request
app.post('/v1/auth/response', { app.post('/v1/auth/response', {
preHandler: app.authenticate, preHandler: app.authenticate,