Press n or j to go to the next uncovered block, b, p or k for the previous block.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 | 56x 56x 51x 51x 51x 21x 30x 24x 24x 24x 3x 21x 3x 18x 18x 9x 9x 9x 9x 6x 3x 6x 6x | import { createRoute, RouteHandler, z } from '@hono/zod-openapi' import { ErrorSchema, AuthCallbackResponseSchema } from '../../schema/drive' import { EnvHono } from '../..' import { exchangeCodeForTokens } from '../../utils/oauth' export const callbackRoute = createRoute({ method: 'get', path: '/callback', request: { query: z.object({ code: z.string().describe('Authorization code from Google OAuth'), scope: z.string().optional().describe('OAuth scope'), error: z.string().optional().describe('OAuth error if any') }) }, responses: { 200: { content: { 'application/json': { schema: AuthCallbackResponseSchema } }, description: 'OAuth callback processed successfully' }, 400: { content: { 'application/json': { schema: ErrorSchema } }, description: 'Bad request or OAuth error' }, 500: { content: { 'application/json': { schema: ErrorSchema } }, description: 'Internal server error' } }, tags: ['Authentication'] }) export const callbackHandler: RouteHandler<typeof callbackRoute, EnvHono> = async (c) => { try { const { GOOGLE_CLIENT_ID, GOOGLE_CLIENT_SECRET } = c.env if (!GOOGLE_CLIENT_ID || !GOOGLE_CLIENT_SECRET) { return c.json({ error: 'Missing required environment variables' }, 400) } const url = new URL(c.req.url) const code = url.searchParams.get('code') const error = url.searchParams.get('error') if (error) { return c.json({ error: 'OAuth error', details: error }, 400) } if (!code) { return c.json({ error: 'Missing authorization code' }, 400) } // Exchange authorization code for tokens using type-safe function let tokens try { tokens = await exchangeCodeForTokens({ clientId: GOOGLE_CLIENT_ID, clientSecret: GOOGLE_CLIENT_SECRET, code: code, redirectUri: 'http://localhost:3000/api/drive/callback' }) } catch (error) { console.error('Token exchange failed:', error) return c.json({ error: 'Failed to exchange authorization code for tokens', details: error instanceof Error ? error.message : 'Unknown error' }, 500) } console.log('Received tokens:', tokens) if (!tokens.refresh_token) { return c.json({ success: false, message: 'No refresh token received. This may happen if the app was already authorized. Try revoking access at https://myaccount.google.com/permissions and re-authorize.', accessToken: tokens.access_token ? 'Access token received' : 'No access token' }, 200) } return c.json({ success: true, refreshToken: tokens.refresh_token, message: `Refresh Token obtained! Add this to your .dev.vars file: GOOGLE_REFRESH_TOKEN=${tokens.refresh_token}` }, 200) } catch (error) { console.error('OAuth callback error:', error) return c.json({ error: 'Failed to exchange code for tokens', details: error instanceof Error ? error.message : 'Unknown error' }, 500) } } |