Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

api implementation for OpenID Connect users #207

Merged
merged 41 commits into from
Feb 7, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
41 commits
Select commit Hold shift + click to select a range
e4c03d1
api implementation for OpenID Connect users
koba-ninkigumi Jan 14, 2022
fde261c
signInWithOpenIDConnect
koba-ninkigumi Jan 19, 2022
0c5df5d
add signInWithOpenIDConnect method
Jan 24, 2022
f59dc7f
add signInWithOpenIDConnect method
Jan 24, 2022
04eaded
add signInWithOpenIDConnect method
Jan 24, 2022
719534c
add signInWithOpenIDConnect method
Jan 26, 2022
e2b40c8
add signInWithOpenIDConnect method
Jan 26, 2022
8ac4f43
add signInWithOpenIDConnect method @JO @kangmingtay
Jan 26, 2022
30eeb54
add signInWithOpenIDConnect method @JO @kangmingtay
Jan 26, 2022
a10b6b0
add signInWithOpenIDConnect method @JO @kangmingtay
Jan 26, 2022
b22996d
add signInWithOpenIDConnect method @J0 @kangmingtay
Jan 27, 2022
999d247
add signInWithOpenIDConnect method @J0 @kangmingtay
Jan 27, 2022
18cedc7
add signInWithOpenIDConnect method @J0 @kangmingtay
Jan 27, 2022
da4f83f
add signInWithOpenIDConnect method @J0 @kangmingtay
Jan 27, 2022
bb0164c
add signInWithOpenIDConnect method @J0 @kangmingtay
Jan 27, 2022
825cce8
add signInWithOpenIDConnect method @J0 @kangmingtay
Jan 27, 2022
521c297
add signInWithOpenIDConnect method @J0 @kangmingtay
Jan 27, 2022
c24c4a5
add signInWithOpenIDConnect method @J0 @kangmingtay
Jan 27, 2022
fa6d628
add signInWithOpenIDConnect method @J0 @kangmingtay
Jan 28, 2022
e7a4d03
add signInWithOpenIDConnect method @J0 @kangmingtay
Jan 29, 2022
e46535e
Merge branch 'supabase:master' into patch-1
koba-ninkigumi Feb 1, 2022
d7c0b81
Update src/GoTrueClient.ts
koba-ninkigumi Feb 3, 2022
b904bd7
Update src/GoTrueClient.ts
koba-ninkigumi Feb 3, 2022
fe80b8f
Update test/GoTrueClient.test.ts
koba-ninkigumi Feb 3, 2022
239abdb
Update src/lib/types.ts
koba-ninkigumi Feb 3, 2022
4847822
Update src/lib/types.ts
koba-ninkigumi Feb 3, 2022
f569e3c
Update src/lib/types.ts
koba-ninkigumi Feb 3, 2022
7f79d18
Update src/GoTrueClient.ts
koba-ninkigumi Feb 3, 2022
6c8eb95
Update src/GoTrueClient.ts
koba-ninkigumi Feb 3, 2022
aa9b27d
Update src/GoTrueClient.ts
koba-ninkigumi Feb 3, 2022
7fbba0b
Update src/GoTrueClient.ts
koba-ninkigumi Feb 3, 2022
833ca89
Update GoTrueApi.ts
koba-ninkigumi Feb 3, 2022
c46f57c
Update GoTrueClient.test.ts
koba-ninkigumi Feb 3, 2022
f999544
Update GoTrueApi.ts
koba-ninkigumi Feb 3, 2022
f9ac9d6
Update GoTrueClient.ts
koba-ninkigumi Feb 3, 2022
639c126
Update GoTrueClient.test.ts
koba-ninkigumi Feb 3, 2022
39299c2
Update GoTrueClient.test.ts
koba-ninkigumi Feb 4, 2022
3a9cae7
Update GoTrueClient.test.ts
koba-ninkigumi Feb 4, 2022
0ec8b96
Update types.ts
koba-ninkigumi Feb 4, 2022
cb6e5bf
Update GoTrueClient.test.ts
koba-ninkigumi Feb 4, 2022
ec80787
Update GoTrueClient.test.ts
koba-ninkigumi Feb 4, 2022
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
27 changes: 27 additions & 0 deletions src/GoTrueApi.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import {
UserAttributes,
CookieOptions,
User,
OpenIDConnectCredentials
} from './lib/types'
import { COOKIE_OPTIONS } from './lib/constants'
import { setCookies, getCookieString } from './lib/cookies'
Expand Down Expand Up @@ -215,6 +216,32 @@ export default class GoTrueApi {
}
}

/**
* Logs in an OpenID Connect user using their id_token.
* @param id_token The IDToken of the user.
* @param nonce The nonce of the user. The nonce is a random value generated by the developer (= yourself) before the initial grant is started. You should check the OpenID Connect specification for details. https://openid.net/developers/specs/
* @param provider The provider of the user.
* @param client_id The clientID of the user.
* @param issuer The issuer of the user.
*/
async signInWithOpenIDConnect({ id_token, nonce, client_id, issuer, provider }:OpenIDConnectCredentials): Promise<{ data: Session | null; error: ApiError | null }> {
try {
const headers = { ...this.headers }
const queryString = '?grant_type=id_token'
const data = await post(
this.fetch,
`${this.url}/token${queryString}`,
{ id_token, nonce, client_id, issuer, provider },
{ headers }
)
const session = { ...data }
if (session.expires_in) session.expires_at = expiresAt(data.expires_in)
return { data: session, error: null }
} catch (e) {
return { data: null, error: e as ApiError }
}
}

/**
* Sends a magic login link to an email address.
* @param email The email address of the user.
Expand Down
29 changes: 27 additions & 2 deletions src/GoTrueClient.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ import type {
CookieOptions,
UserCredentials,
VerifyOTPParams,
OpenIDConnectCredentials,
} from './lib/types'

polyfillGlobalThis() // Make "globalThis" available
Expand Down Expand Up @@ -186,7 +187,7 @@ export default class GoTrueClient {
* @param scopes A space-separated list of scopes granted to the OAuth application.
*/
async signIn(
{ email, phone, password, refreshToken, provider }: UserCredentials,
{ email, phone, password, refreshToken, provider, oidc }: UserCredentials,
options: {
redirectTo?: string
scopes?: string
Expand Down Expand Up @@ -240,7 +241,10 @@ export default class GoTrueClient {
scopes: options.scopes,
})
}
throw new Error(`You must provide either an email, phone number or a third-party provider.`)
if (oidc) {
return this._handleOpenIDConnectSignIn(oidc)
}
throw new Error(`You must provide either an email, phone number, a third-party provider or OpenID Connect.`)
} catch (e) {
return { user: null, session: null, error: e as ApiError }
}
Expand Down Expand Up @@ -558,6 +562,27 @@ export default class GoTrueClient {
}
}

private async _handleOpenIDConnectSignIn(
{ id_token, nonce, client_id, issuer, provider }: OpenIDConnectCredentials
): Promise<{
session: Session | null
user: User | null
error: ApiError | null
}> {
if (id_token && nonce && ( (client_id && issuer) || provider) ) {
try {
const { data, error } = await this.api.signInWithOpenIDConnect({id_token, nonce, client_id, issuer, provider})
if (error || !data) return { user: null, session: null, error }
this._saveSession(data)
this._notifyAllSubscribers('SIGNED_IN')
return { user: data.user, session: data, error: null }
} catch (e) {
return { user: null, session: null, error: e as ApiError }
}
}
throw new Error(`You must provide a OpenID Connect provider with your id token and nonce.`)
}

/**
* Attempts to get the session from LocalStorage
* Note: this should never be async (even for React Native), as we need it to return immediately in the constructor.
Expand Down
9 changes: 9 additions & 0 deletions src/lib/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -174,9 +174,18 @@ export interface UserCredentials {
refreshToken?: string
// (Optional) The name of the provider.
provider?: Provider
oidc?: OpenIDConnectCredentials
}

export interface VerifyOTPParams {
phone: string
token: string
}

export interface OpenIDConnectCredentials {
id_token: string
nonce: string
provider?: Provider
client_id?: string
issuer?: string
}
36 changes: 36 additions & 0 deletions test/GoTrueClient.test.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import { OpenIDConnectCredentials } from '../src'
import {
authClient as auth,
authClientWithSession as authWithSession,
Expand Down Expand Up @@ -280,6 +281,41 @@ describe('GoTrueClient', () => {
expect(user?.email).toBe(email)
})

test('signIn with OpenIDConnect wrong id_token', async () => {
const oidc: OpenIDConnectCredentials = {
id_token: 'abcde',
nonce: 'random value',
provider: 'google'
}
const { session, user, error } = await auth.signIn({oidc})

expect(error).not.toBeNull()
expect(session).toBeNull()
expect(user).toBeNull()
})

test('signIn with OpenIDConnect both client_id and provider are null', async () => {
const t = async ()=>{
const oidc: OpenIDConnectCredentials = {
id_token: 'abcde',
nonce: 'random value',
}
await auth.signIn({oidc})
}
await expect(t).rejects.toThrow(Error)
})

test('signIn with OpenIDConnect both id_token and client_id is null', async () => {
const t = async ()=>{
const oidc: any = {
nonce: 'random value',
provider: 'google'
}
await auth.signIn({oidc})
}
await expect(t).rejects.toThrow(Error)
})

test('signOut', async () => {
const { email, password } = mockUserCredentials()

Expand Down