You cannot select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
41 lines
1.2 KiB
TypeScript
41 lines
1.2 KiB
TypeScript
import type { APIContext } from 'astro'
|
|
import { init, createId } from '@paralleldrive/cuid2'
|
|
import { createHash } from 'node:crypto'
|
|
|
|
export async function GET({ cookies }: APIContext) {
|
|
const generateId = init({ length: 40 })
|
|
|
|
const googleOauthState = createId()
|
|
|
|
cookies.set('google_oauth_state', googleOauthState, {
|
|
path: '/',
|
|
})
|
|
|
|
const googleCodeChallenge = generateId()
|
|
const codeChallenge = createHash('sha256').update(googleCodeChallenge).digest('base64url')
|
|
|
|
cookies.set('google_code_challenge', googleCodeChallenge, {
|
|
path: '/',
|
|
})
|
|
|
|
const authorizationUrl = new URL('https://accounts.google.com/o/oauth2/v2/auth')
|
|
authorizationUrl.search = new URLSearchParams({
|
|
access_type: 'offline',
|
|
scope: 'openid email profile',
|
|
prompt: 'consent',
|
|
response_type: 'code',
|
|
client_id: import.meta.env.OAUTH_GOOGLE_CLIENT_ID,
|
|
redirect_uri: import.meta.env.OAUTH_GOOGLE_CALLBACK_URL,
|
|
state: googleOauthState,
|
|
code_challenge: codeChallenge,
|
|
code_challenge_method: 'S256',
|
|
}).toString()
|
|
|
|
return new Response(null, {
|
|
status: 302,
|
|
headers: {
|
|
Location: authorizationUrl.toString(),
|
|
},
|
|
})
|
|
}
|