diff --git a/src/pages/api/[...path].ts b/src/pages/api/[...path].ts index 732369c9..3c79728a 100644 --- a/src/pages/api/[...path].ts +++ b/src/pages/api/[...path].ts @@ -3,6 +3,7 @@ import { Hono } from 'hono' import { getCookie, setCookie } from 'hono/cookie' import { parse, safeParse } from 'valibot' import { makeOauth2Client, type Credentials, accessTokenResponseSchema, fetchUserInfo } from '../../utils/google-oauth' +import { google } from 'googleapis' const app = new Hono<{ Variables: { @@ -29,7 +30,11 @@ const googleRoutes = app.basePath('/google') await next() }) .get('/get-user-info', async c => { - return c.json(await fetchUserInfo(c.var.googleOauthCredentials.access_token)) + const userInfo = await fetchUserInfo(c.var.googleOauthCredentials.access_token) + + return c.json({success: userInfo.success, ...(userInfo.success ? { + data: userInfo.data + } : {})}) }) .get('/get-nnote', async c => { const driveClient = google.drive({ version: 'v2', auth: c.var.googleOauthClient }) diff --git a/src/utils/google-oauth/index.ts b/src/utils/google-oauth/index.ts index 8c178027..0f5f966e 100644 --- a/src/utils/google-oauth/index.ts +++ b/src/utils/google-oauth/index.ts @@ -1,19 +1,20 @@ import { google } from "googleapis" -import { number, object, parse, string, type Output, type BaseSchema, any } from "valibot" +import { number, object, parse, string, type Output, type BaseSchema, any, type Input, safeParse } from "valibot" + +export const redirectUri = new URL('/google-oauth/callback', import.meta.env.DEV ? (import.meta.env.DEV_SITE ?? 'http://localhost:4321') : import.meta.env.SITE).href -export const redirectUri = new URL('/google-oauth/callback', import.meta.env.DEV ? 'http://localhost:4321' : import.meta.env.SITE).href export const makeOauth2Client = () => new google.auth.OAuth2({ clientId: import.meta.env.GOOGLE_OAUTH_CLIENT_ID, - clientSecret: import.meta.env.GOOGLE_OAUTH_CLIENT_ID, + clientSecret: import.meta.env.GOOGLE_OAUTH_CLIENT_SECRET, redirectUri }) export const accessTokenResponseSchema = object({ access_token: string(), expires_in: number(), - refresh_token: string(), scope: string(), - token_type: string() + token_type: string(), + id_token: string() }) export type Credentials = Output @@ -29,6 +30,7 @@ export const createAuthRedirectURL = (scopes: string[]) => { params.append('redirect_uri', redirectUri) const result = `https://accounts.google.com/o/oauth2/v2/auth?${params}` + console.log(result) return result } @@ -41,6 +43,7 @@ export const fetchAccessToken = async (callbackCode: string) => { data.append('client_secret', import.meta.env.GOOGLE_OAUTH_CLIENT_SECRET) data.append('redirect_uri', redirectUri) data.append('grant_type', 'authorization_code') + data.append('redirect_uri', redirectUri) const req = new Request(targetUrl, { body: data, @@ -50,22 +53,49 @@ export const fetchAccessToken = async (callbackCode: string) => { method: 'POST' }) const json = await fetch(req).then(res => res.json()) - + console.log(json) return parse(accessTokenResponseSchema, json) } -const makeFetchAPIFunc = (scope: string, schema: Schema) => async (accessToken: string) => { - const result = await fetch(scope, { +type FetchResult = { + response: Response +} & ({ + success: true + data: Schema +} | { + success: false +}) +const makeFetchAPIFunc = (scope: string, schema: Schema) => async (accessToken: string): Promise> => { + const token = `Bearer ${accessToken}` + const req = new Request(scope, { headers: { - Authorization: `Bearer ${accessToken}` + "x-goog-api-client": "gdcl/7.0.1 gl-node/20.11.0", + "Accept-Encoding": "gzip", + "User-Agent": "google-api-nodejs-client/7.0.1 (gzip)", + "Authorization": token + } + }) + const res = await fetch(req) + const result = await res.json() + console.log(result) + const parsed = safeParse(schema, result) + if (parsed.success) { + return { + success: true, + data: result, + response: res } - }).then(res => res.json()) - - return parse(schema, result) + } + return { + success: false, + response: res + } } -export const fetchUserInfo = makeFetchAPIFunc('https://www.googleapis.com/oauth2/v1/userinfo', object({ +export const fetchUserInfo = makeFetchAPIFunc('https://www.googleapis.com/oauth2/v2/userinfo', object({ id: string(), name: string(), given_name: string(), - family_name: string() + family_name: string(), + picture: string(), + locale: string() }))