Skip to content

Commit

Permalink
fix(@hono/oauth-providers): Added missing URL parameters prompt, logi…
Browse files Browse the repository at this point in the history
…n_hint, and access_type in the Google OAuth provider. (#697)

* fix: google provider attach custom parameters

* fix format

* Create rare-fishes-sort.md
  • Loading branch information
taishinaritomi authored Aug 19, 2024
1 parent 2528a9f commit c3b67a6
Show file tree
Hide file tree
Showing 4 changed files with 42 additions and 1 deletion.
5 changes: 5 additions & 0 deletions .changeset/rare-fishes-sort.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"@hono/oauth-providers": patch
---

fix(@hono/oauth-providers): google provider attach custom parameters
7 changes: 7 additions & 0 deletions packages/oauth-providers/src/providers/google/authFlow.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ type GoogleAuthFlow = {
state?: string
login_hint?: string
prompt?: 'none' | 'consent' | 'select_account'
access_type?: 'offline' | 'online'
}

export class AuthFlow {
Expand All @@ -28,6 +29,7 @@ export class AuthFlow {
prompt: 'none' | 'consent' | 'select_account' | undefined
user: Partial<GoogleUser> | undefined
granted_scopes: string[] | undefined
access_type: 'offline' | 'online' | undefined

constructor({
client_id,
Expand All @@ -39,6 +41,7 @@ export class AuthFlow {
state,
code,
token,
access_type,
}: GoogleAuthFlow) {
this.client_id = client_id
this.client_secret = client_secret
Expand All @@ -51,6 +54,7 @@ export class AuthFlow {
this.token = token
this.user = undefined
this.granted_scopes = undefined
this.access_type = access_type

if (
this.client_id === undefined ||
Expand All @@ -71,6 +75,9 @@ export class AuthFlow {
include_granted_scopes: true,
scope: this.scope.join(' '),
state: this.state,
prompt: this.prompt,
login_hint: this.login_hint,
access_type: this.access_type,
})
return `https://accounts.google.com/o/oauth2/v2/auth?${parsedOptions}`
}
Expand Down
4 changes: 3 additions & 1 deletion packages/oauth-providers/src/providers/google/googleAuth.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import type { MiddlewareHandler } from 'hono'
import { getCookie, setCookie } from 'hono/cookie'
import { env } from 'hono/adapter'
import { getCookie, setCookie } from 'hono/cookie'
import { HTTPException } from 'hono/http-exception'

import { getRandomState } from '../../utils/getRandomState'
Expand All @@ -10,6 +10,7 @@ export function googleAuth(options: {
scope: string[]
login_hint?: string
prompt?: 'none' | 'consent' | 'select_account'
access_type?: 'online' | 'offline'
client_id?: string
client_secret?: string
state?: string
Expand All @@ -24,6 +25,7 @@ export function googleAuth(options: {
redirect_uri: options.redirect_uri || c.req.url.split('?')[0],
login_hint: options.login_hint,
prompt: options.prompt,
access_type: options.access_type,
scope: options.scope,
state: newState,
code: c.req.query('code'),
Expand Down
27 changes: 27 additions & 0 deletions packages/oauth-providers/test/index.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,18 @@ describe('OAuth Middleware', () => {
redirect_uri: 'http://localhost:3000/google',
})(c, next)
})
app.use('/google-custom-params', (c, next) => {
return googleAuth({
client_id,
client_secret,
scope: ['openid', 'email', 'profile'],
redirect_uri: 'http://localhost:3000/google',
login_hint: 'test-login-hint',
prompt: 'select_account',
state: 'test-state',
access_type: 'offline',
})(c, next)
})
app.get('/google', (c) => {
const user = c.get('user-google')
const token = c.get('token')
Expand Down Expand Up @@ -356,6 +368,21 @@ describe('OAuth Middleware', () => {
expect(redirectUrl.searchParams.get('redirect_uri')).toBe('http://localhost:3000/google')
})

it('Should attach custom parameters', async () => {
const res = await app.request('/google-custom-params')
expect(res).not.toBeNull()
expect(res.status).toBe(302)

const redirectLocation = res.headers.get('location')!
const redirectUrl = new URL(redirectLocation)
expect(redirectUrl.searchParams.get('redirect_uri')).toBe('http://localhost:3000/google')
expect(redirectUrl.searchParams.get('scope')).toBe('openid email profile')
expect(redirectUrl.searchParams.get('login_hint')).toBe('test-login-hint')
expect(redirectUrl.searchParams.get('prompt')).toBe('select_account')
expect(redirectUrl.searchParams.get('state')).toBe('test-state')
expect(redirectUrl.searchParams.get('access_type')).toBe('offline')
})

it('Prevent CSRF attack', async () => {
const res = await app.request(`/google?code=${dummyCode}&state=malware-state`)

Expand Down

0 comments on commit c3b67a6

Please sign in to comment.