|
| 1 | +import { serve } from '@hono/node-server'; |
| 2 | +import { Hono } from 'hono'; |
| 3 | +import { cors } from 'hono/cors' |
| 4 | +import { HTTPException } from 'hono/http-exception'; |
1 | 5 | import * as fs from 'node:fs/promises'; |
2 | | -import { type IncomingMessage, ServerResponse, createServer } from 'node:http'; |
3 | 6 | import * as os from 'node:os'; |
4 | 7 | import path from 'node:path'; |
5 | 8 | import open from 'open'; |
6 | 9 |
|
| 10 | +import { config } from '../config.js'; |
| 11 | +import { ajv } from '../utils/ajv.js'; |
| 12 | + |
| 13 | +const schema = { |
| 14 | + type: 'object', |
| 15 | + properties: { |
| 16 | + accessToken: { |
| 17 | + type: 'string', |
| 18 | + }, |
| 19 | + email: { |
| 20 | + type: 'string', |
| 21 | + }, |
| 22 | + userId: { |
| 23 | + type: 'string', |
| 24 | + }, |
| 25 | + expiry: { |
| 26 | + type: 'string', |
| 27 | + } |
| 28 | + }, |
| 29 | + additionalProperties: false, |
| 30 | + required: ['accessToken', 'email', 'userId', 'expiry'], |
| 31 | +} |
| 32 | + |
| 33 | +interface Credentials { |
| 34 | + accessToken: string; |
| 35 | + email: string; |
| 36 | + userId: string; |
| 37 | + expiry: string; |
| 38 | +} |
| 39 | + |
7 | 40 | export class LoginOrchestrator { |
8 | 41 | static async run(){ |
9 | | - const server = createServer((req, res) => { |
10 | | - LoginOrchestrator.handleRequests(req, res); |
11 | | - }); |
| 42 | + const server = new Hono(); |
12 | 43 |
|
13 | | - server.listen(51_039, 'localhost', () => { |
| 44 | + server.use('*', cors({ origin: config.corsAllowedOrigins })) |
| 45 | + server.post('/', async (c) => { |
| 46 | + const body = await c.req.json(); |
| 47 | + if (!ajv.validate(schema, body)) { |
| 48 | + throw new HTTPException(400, { message: ajv.errorsText() }) |
| 49 | + } |
| 50 | + |
| 51 | + await LoginOrchestrator.saveCredentials(body as unknown as Credentials) |
| 52 | + return c.text('Success', 200); |
| 53 | + }); |
| 54 | + |
| 55 | + serve({ |
| 56 | + fetch: server.fetch, |
| 57 | + port: config.loginServerPort, |
| 58 | + }, () => { |
14 | 59 | console.log('Opening CLI auth page...') |
15 | 60 | open('http://localhost:3000/auth/cli'); |
16 | 61 | }) |
17 | 62 | } |
18 | 63 |
|
19 | | - private static async handleRequests(req: IncomingMessage, res: ServerResponse<IncomingMessage>) { |
20 | | - try { |
21 | | - if (req.method !== 'POST') { |
22 | | - res.writeHead(400, { 'Content-Type': 'application/json' }); |
23 | | - return; |
24 | | - } |
25 | | - |
26 | | - const json = await new Promise((resolve) => { |
27 | | - const buf = new Array<Uint8Array>() |
28 | | - req.on('data', (chunk) => { |
29 | | - buf.push(chunk); |
30 | | - }).on('end', () => { |
31 | | - const body = Buffer.concat(buf).toString(); |
32 | | - const json = JSON.parse(body); |
33 | | - resolve(json); |
34 | | - }).on('error', (err) => { |
35 | | - console.error(err); |
36 | | - }) |
37 | | - }); |
38 | | - |
39 | | - const credentialsPath = path.join(os.homedir(), '.codify', 'credentials.json'); |
40 | | - console.log(`Saving credentials to ${credentialsPath}`); |
41 | | - await fs.writeFile(credentialsPath, JSON.stringify(json)); |
42 | | - |
43 | | - res.writeHead(200, { 'Content-Type': 'application/json' }); |
44 | | - process.exit(0); |
45 | | - } catch (error) { |
46 | | - console.error(error); |
47 | | - res.writeHead(500, { 'Content-Type': 'application/json' }); |
48 | | - process.exit(1); |
49 | | - } |
| 64 | + private static async saveCredentials(credentials: Credentials) { |
| 65 | + const credentialsPath = path.join(os.homedir(), '.codify', 'credentials.json'); |
| 66 | + console.log(`Saving credentials to ${credentialsPath}`); |
| 67 | + await fs.writeFile(credentialsPath, JSON.stringify(credentials)); |
50 | 68 | } |
51 | 69 | } |
0 commit comments