@supabase/gotrue-js 2.0.1 → 2.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +1 -1
- package/dist/main/GoTrueAdminApi.d.ts +6 -1
- package/dist/main/GoTrueAdminApi.d.ts.map +1 -1
- package/dist/main/GoTrueAdminApi.js +40 -2
- package/dist/main/GoTrueAdminApi.js.map +1 -1
- package/dist/main/GoTrueClient.d.ts +33 -1
- package/dist/main/GoTrueClient.d.ts.map +1 -1
- package/dist/main/GoTrueClient.js +148 -1
- package/dist/main/GoTrueClient.js.map +1 -1
- package/dist/main/index.d.ts.map +1 -1
- package/dist/main/index.js.map +1 -1
- package/dist/main/lib/helpers.d.ts +1 -0
- package/dist/main/lib/helpers.d.ts.map +1 -1
- package/dist/main/lib/helpers.js +11 -1
- package/dist/main/lib/helpers.js.map +1 -1
- package/dist/main/lib/types.d.ts +348 -1
- package/dist/main/lib/types.d.ts.map +1 -1
- package/dist/main/lib/version.d.ts +1 -1
- package/dist/main/lib/version.js +1 -1
- package/dist/module/GoTrueAdminApi.d.ts +6 -1
- package/dist/module/GoTrueAdminApi.d.ts.map +1 -1
- package/dist/module/GoTrueAdminApi.js +40 -2
- package/dist/module/GoTrueAdminApi.js.map +1 -1
- package/dist/module/GoTrueClient.d.ts +33 -1
- package/dist/module/GoTrueClient.d.ts.map +1 -1
- package/dist/module/GoTrueClient.js +149 -2
- package/dist/module/GoTrueClient.js.map +1 -1
- package/dist/module/index.d.ts.map +1 -1
- package/dist/module/index.js.map +1 -1
- package/dist/module/lib/helpers.d.ts +1 -0
- package/dist/module/lib/helpers.d.ts.map +1 -1
- package/dist/module/lib/helpers.js +9 -0
- package/dist/module/lib/helpers.js.map +1 -1
- package/dist/module/lib/types.d.ts +348 -1
- package/dist/module/lib/types.d.ts.map +1 -1
- package/dist/module/lib/version.d.ts +1 -1
- package/dist/module/lib/version.js +1 -1
- package/package.json +2 -2
- package/src/GoTrueAdminApi.ts +63 -3
- package/src/GoTrueClient.ts +198 -2
- package/src/index.ts +0 -1
- package/src/lib/helpers.ts +11 -0
- package/src/lib/types.ts +393 -0
- package/src/lib/version.ts +1 -1
package/src/GoTrueClient.ts
CHANGED
|
@@ -17,7 +17,6 @@ import {
|
|
|
17
17
|
} from './lib/errors'
|
|
18
18
|
import { Fetch, _request, _sessionResponse, _userResponse } from './lib/fetch'
|
|
19
19
|
import {
|
|
20
|
-
decodeBase64URL,
|
|
21
20
|
Deferred,
|
|
22
21
|
getItemAsync,
|
|
23
22
|
getParameterByName,
|
|
@@ -26,6 +25,7 @@ import {
|
|
|
26
25
|
resolveFetch,
|
|
27
26
|
setItemAsync,
|
|
28
27
|
uuid,
|
|
28
|
+
decodeJWTPayload,
|
|
29
29
|
} from './lib/helpers'
|
|
30
30
|
import localStorageAdapter from './lib/local-storage'
|
|
31
31
|
import { polyfillGlobalThis } from './lib/polyfills'
|
|
@@ -48,6 +48,20 @@ import type {
|
|
|
48
48
|
UserAttributes,
|
|
49
49
|
UserResponse,
|
|
50
50
|
VerifyOtpParams,
|
|
51
|
+
GoTrueMFAApi,
|
|
52
|
+
MFAEnrollParams,
|
|
53
|
+
AuthMFAEnrollResponse,
|
|
54
|
+
MFAChallengeParams,
|
|
55
|
+
AuthMFAChallengeResponse,
|
|
56
|
+
MFAUnenrollParams,
|
|
57
|
+
AuthMFAUnenrollResponse,
|
|
58
|
+
MFAVerifyParams,
|
|
59
|
+
AuthMFAVerifyResponse,
|
|
60
|
+
AuthMFAListFactorsResponse,
|
|
61
|
+
AMREntry,
|
|
62
|
+
AuthMFAGetAuthenticatorAssuranceLevelResponse,
|
|
63
|
+
AuthenticatorAssuranceLevels,
|
|
64
|
+
Factor,
|
|
51
65
|
} from './lib/types'
|
|
52
66
|
|
|
53
67
|
polyfillGlobalThis() // Make "globalThis" available
|
|
@@ -67,6 +81,10 @@ export default class GoTrueClient {
|
|
|
67
81
|
* These methods should only be used in a trusted server-side environment.
|
|
68
82
|
*/
|
|
69
83
|
admin: GoTrueAdminApi
|
|
84
|
+
/**
|
|
85
|
+
* Namespace for the MFA methods.
|
|
86
|
+
*/
|
|
87
|
+
mfa: GoTrueMFAApi
|
|
70
88
|
/**
|
|
71
89
|
* The storage key used to identify the values saved in localStorage
|
|
72
90
|
*/
|
|
@@ -121,6 +139,14 @@ export default class GoTrueClient {
|
|
|
121
139
|
this.detectSessionInUrl = settings.detectSessionInUrl
|
|
122
140
|
|
|
123
141
|
this.initialize()
|
|
142
|
+
this.mfa = {
|
|
143
|
+
verify: this._verify.bind(this),
|
|
144
|
+
enroll: this._enroll.bind(this),
|
|
145
|
+
unenroll: this._unenroll.bind(this),
|
|
146
|
+
challenge: this._challenge.bind(this),
|
|
147
|
+
listFactors: this._listFactors.bind(this),
|
|
148
|
+
getAuthenticatorAssuranceLevel: this._getAuthenticatorAssuranceLevel.bind(this),
|
|
149
|
+
}
|
|
124
150
|
}
|
|
125
151
|
|
|
126
152
|
/**
|
|
@@ -530,6 +556,17 @@ export default class GoTrueClient {
|
|
|
530
556
|
}
|
|
531
557
|
}
|
|
532
558
|
|
|
559
|
+
/**
|
|
560
|
+
* Decodes a JWT (without performing any validation).
|
|
561
|
+
*/
|
|
562
|
+
private _decodeJWT(jwt: string): {
|
|
563
|
+
exp?: number
|
|
564
|
+
aal?: AuthenticatorAssuranceLevels | null
|
|
565
|
+
amr?: AMREntry[] | null
|
|
566
|
+
} {
|
|
567
|
+
return decodeJWTPayload(jwt)
|
|
568
|
+
}
|
|
569
|
+
|
|
533
570
|
/**
|
|
534
571
|
* Sets the session data from the current session. If the current session is expired, setSession will take care of refreshing it to obtain a new session.
|
|
535
572
|
* If the refresh token in the current session is invalid and the current session has expired, an error will be thrown.
|
|
@@ -545,7 +582,8 @@ export default class GoTrueClient {
|
|
|
545
582
|
let hasExpired = true
|
|
546
583
|
let session: Session | null = null
|
|
547
584
|
if (currentSession.access_token && currentSession.access_token.split('.')[1]) {
|
|
548
|
-
const payload =
|
|
585
|
+
const payload = this._decodeJWT(currentSession.access_token)
|
|
586
|
+
|
|
549
587
|
if (payload.exp) {
|
|
550
588
|
expiresAt = payload.exp
|
|
551
589
|
hasExpired = expiresAt <= timeNow
|
|
@@ -1005,4 +1043,162 @@ export default class GoTrueClient {
|
|
|
1005
1043
|
}
|
|
1006
1044
|
return `${this.url}/authorize?${urlParams.join('&')}`
|
|
1007
1045
|
}
|
|
1046
|
+
|
|
1047
|
+
private async _unenroll(params: MFAUnenrollParams): Promise<AuthMFAUnenrollResponse> {
|
|
1048
|
+
const { data: sessionData, error: sessionError } = await this.getSession()
|
|
1049
|
+
if (sessionError) {
|
|
1050
|
+
return { data: null, error: sessionError }
|
|
1051
|
+
}
|
|
1052
|
+
|
|
1053
|
+
return await _request(this.fetch, 'DELETE', `${this.url}/factors/${params.factorId}`, {
|
|
1054
|
+
headers: this.headers,
|
|
1055
|
+
jwt: sessionData?.session?.access_token,
|
|
1056
|
+
})
|
|
1057
|
+
}
|
|
1058
|
+
|
|
1059
|
+
/**
|
|
1060
|
+
* Deletes a registered factor from GoTrue
|
|
1061
|
+
* @param friendlyName Human readable name assigned to a device
|
|
1062
|
+
* @param factorType device which we're validating against. Can only be TOTP for now.
|
|
1063
|
+
* @param issuer domain which the user is enrolling with
|
|
1064
|
+
*/
|
|
1065
|
+
private async _enroll(params: MFAEnrollParams): Promise<AuthMFAEnrollResponse> {
|
|
1066
|
+
const { data: sessionData, error: sessionError } = await this.getSession()
|
|
1067
|
+
if (sessionError) {
|
|
1068
|
+
return { data: null, error: sessionError }
|
|
1069
|
+
}
|
|
1070
|
+
|
|
1071
|
+
const { data, error } = await _request(this.fetch, 'POST', `${this.url}/factors`, {
|
|
1072
|
+
body: {
|
|
1073
|
+
friendly_name: params.friendlyName,
|
|
1074
|
+
factor_type: params.factorType,
|
|
1075
|
+
issuer: params.issuer,
|
|
1076
|
+
},
|
|
1077
|
+
headers: this.headers,
|
|
1078
|
+
jwt: sessionData?.session?.access_token,
|
|
1079
|
+
})
|
|
1080
|
+
|
|
1081
|
+
if (error) {
|
|
1082
|
+
return { data: null, error }
|
|
1083
|
+
}
|
|
1084
|
+
|
|
1085
|
+
if (data?.totp?.qr_code) {
|
|
1086
|
+
data.totp.qr_code = `data:image/svg+xml;utf-8,${data.totp.qr_code}`
|
|
1087
|
+
}
|
|
1088
|
+
|
|
1089
|
+
return { data, error: null }
|
|
1090
|
+
}
|
|
1091
|
+
|
|
1092
|
+
/**
|
|
1093
|
+
* Validates a device as part of the enrollment step.
|
|
1094
|
+
* @param factorID System assigned identifier for authenticator device as returned by enroll
|
|
1095
|
+
* @param code Code Generated by an authenticator device
|
|
1096
|
+
*/
|
|
1097
|
+
private async _verify(params: MFAVerifyParams): Promise<AuthMFAVerifyResponse> {
|
|
1098
|
+
const { data: sessionData, error: sessionError } = await this.getSession()
|
|
1099
|
+
if (sessionError) {
|
|
1100
|
+
return { data: null, error: sessionError }
|
|
1101
|
+
}
|
|
1102
|
+
|
|
1103
|
+
const { data, error } = await _request(
|
|
1104
|
+
this.fetch,
|
|
1105
|
+
'POST',
|
|
1106
|
+
`${this.url}/factors/${params.factorId}/verify`,
|
|
1107
|
+
{
|
|
1108
|
+
body: { code: params.code, challenge_id: params.challengeId },
|
|
1109
|
+
headers: this.headers,
|
|
1110
|
+
jwt: sessionData?.session?.access_token,
|
|
1111
|
+
}
|
|
1112
|
+
)
|
|
1113
|
+
if (error) {
|
|
1114
|
+
return { data: null, error }
|
|
1115
|
+
}
|
|
1116
|
+
|
|
1117
|
+
await this._saveSession({
|
|
1118
|
+
expires_at: Math.round(Date.now() / 1000) + data.expires_in,
|
|
1119
|
+
...data,
|
|
1120
|
+
})
|
|
1121
|
+
this._notifyAllSubscribers('MFA_CHALLENGE_VERIFIED', data)
|
|
1122
|
+
|
|
1123
|
+
return { data, error }
|
|
1124
|
+
}
|
|
1125
|
+
|
|
1126
|
+
/**
|
|
1127
|
+
* Creates a challenge which a user can verify against
|
|
1128
|
+
* @param factorID System assigned identifier for authenticator device as returned by enroll
|
|
1129
|
+
*/
|
|
1130
|
+
private async _challenge(params: MFAChallengeParams): Promise<AuthMFAChallengeResponse> {
|
|
1131
|
+
const { data: sessionData, error: sessionError } = await this.getSession()
|
|
1132
|
+
if (sessionError) {
|
|
1133
|
+
return { data: null, error: sessionError }
|
|
1134
|
+
}
|
|
1135
|
+
|
|
1136
|
+
return await _request(this.fetch, 'POST', `${this.url}/factors/${params.factorId}/challenge`, {
|
|
1137
|
+
headers: this.headers,
|
|
1138
|
+
jwt: sessionData?.session?.access_token,
|
|
1139
|
+
})
|
|
1140
|
+
}
|
|
1141
|
+
|
|
1142
|
+
/**
|
|
1143
|
+
* Displays all devices for a given user
|
|
1144
|
+
*/
|
|
1145
|
+
private async _listFactors(): Promise<AuthMFAListFactorsResponse> {
|
|
1146
|
+
const {
|
|
1147
|
+
data: { user },
|
|
1148
|
+
error: userError,
|
|
1149
|
+
} = await this.getUser()
|
|
1150
|
+
if (userError) {
|
|
1151
|
+
return { data: null, error: userError }
|
|
1152
|
+
}
|
|
1153
|
+
|
|
1154
|
+
const factors = user?.factors || []
|
|
1155
|
+
const totp = factors.filter(
|
|
1156
|
+
(factor) => factor.factor_type === 'totp' && factor.status === 'verified'
|
|
1157
|
+
)
|
|
1158
|
+
|
|
1159
|
+
return {
|
|
1160
|
+
data: {
|
|
1161
|
+
all: factors,
|
|
1162
|
+
totp,
|
|
1163
|
+
},
|
|
1164
|
+
error: null,
|
|
1165
|
+
}
|
|
1166
|
+
}
|
|
1167
|
+
|
|
1168
|
+
private async _getAuthenticatorAssuranceLevel(): Promise<AuthMFAGetAuthenticatorAssuranceLevelResponse> {
|
|
1169
|
+
const {
|
|
1170
|
+
data: { session },
|
|
1171
|
+
error: sessionError,
|
|
1172
|
+
} = await this.getSession()
|
|
1173
|
+
if (sessionError) {
|
|
1174
|
+
return { data: null, error: sessionError }
|
|
1175
|
+
}
|
|
1176
|
+
if (!session) {
|
|
1177
|
+
return {
|
|
1178
|
+
data: { currentLevel: null, nextLevel: null, currentAuthenticationMethods: [] },
|
|
1179
|
+
error: null,
|
|
1180
|
+
}
|
|
1181
|
+
}
|
|
1182
|
+
|
|
1183
|
+
const payload = this._decodeJWT(session.access_token)
|
|
1184
|
+
|
|
1185
|
+
let currentLevel: AuthenticatorAssuranceLevels | null = null
|
|
1186
|
+
|
|
1187
|
+
if (payload.aal) {
|
|
1188
|
+
currentLevel = payload.aal
|
|
1189
|
+
}
|
|
1190
|
+
|
|
1191
|
+
let nextLevel: AuthenticatorAssuranceLevels | null = currentLevel
|
|
1192
|
+
|
|
1193
|
+
const verifiedFactors =
|
|
1194
|
+
session.user.factors?.filter((factor: Factor) => factor.status === 'verified') ?? []
|
|
1195
|
+
|
|
1196
|
+
if (verifiedFactors.length > 0) {
|
|
1197
|
+
nextLevel = 'aal2'
|
|
1198
|
+
}
|
|
1199
|
+
|
|
1200
|
+
const currentAuthenticationMethods = payload.amr || []
|
|
1201
|
+
|
|
1202
|
+
return { data: { currentLevel, nextLevel, currentAuthenticationMethods }, error: null }
|
|
1203
|
+
}
|
|
1008
1204
|
}
|
package/src/index.ts
CHANGED
package/src/lib/helpers.ts
CHANGED
|
@@ -120,3 +120,14 @@ export class Deferred<T = any> {
|
|
|
120
120
|
})
|
|
121
121
|
}
|
|
122
122
|
}
|
|
123
|
+
// Taken from: https://stackoverflow.com/questions/38552003/how-to-decode-jwt-token-in-javascript-without-using-a-library
|
|
124
|
+
export function decodeJWTPayload(token: string) {
|
|
125
|
+
const parts = token.split('.')
|
|
126
|
+
|
|
127
|
+
if (parts.length !== 3) {
|
|
128
|
+
throw new Error('JWT is not valid: not a JWT structure')
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
const base64Url = parts[1]
|
|
132
|
+
return JSON.parse(decodeBase64URL(base64Url))
|
|
133
|
+
}
|
package/src/lib/types.ts
CHANGED
|
@@ -20,6 +20,11 @@ export type Provider =
|
|
|
20
20
|
| 'twitter'
|
|
21
21
|
| 'workos'
|
|
22
22
|
|
|
23
|
+
/**
|
|
24
|
+
* @experimental
|
|
25
|
+
*/
|
|
26
|
+
export type AuthChangeEventMFA = 'MFA_CHALLENGE_VERIFIED'
|
|
27
|
+
|
|
23
28
|
export type AuthChangeEvent =
|
|
24
29
|
| 'PASSWORD_RECOVERY'
|
|
25
30
|
| 'SIGNED_IN'
|
|
@@ -27,6 +32,7 @@ export type AuthChangeEvent =
|
|
|
27
32
|
| 'TOKEN_REFRESHED'
|
|
28
33
|
| 'USER_UPDATED'
|
|
29
34
|
| 'USER_DELETED'
|
|
35
|
+
| AuthChangeEventMFA
|
|
30
36
|
|
|
31
37
|
export type GoTrueClientOptions = {
|
|
32
38
|
/* The URL of the GoTrue server. */
|
|
@@ -123,6 +129,25 @@ export interface Session {
|
|
|
123
129
|
user: User
|
|
124
130
|
}
|
|
125
131
|
|
|
132
|
+
/**
|
|
133
|
+
* An authentication methord reference (AMR) entry.
|
|
134
|
+
*
|
|
135
|
+
* An entry designates what method was used by the user to verify their
|
|
136
|
+
* identity and at what time.
|
|
137
|
+
*
|
|
138
|
+
* @see {@link GoTrueMFAApi#getAuthenticatorAssuranceLevel}.
|
|
139
|
+
*/
|
|
140
|
+
export interface AMREntry {
|
|
141
|
+
/** Authentication method name. */
|
|
142
|
+
method: 'password' | 'otp' | 'oauth' | 'mfa/totp' | string
|
|
143
|
+
|
|
144
|
+
/**
|
|
145
|
+
* Timestamp when the method was successfully used. Represents number of
|
|
146
|
+
* seconds since 1st January 1970 (UNIX epoch) in UTC.
|
|
147
|
+
*/
|
|
148
|
+
timestamp: number
|
|
149
|
+
}
|
|
150
|
+
|
|
126
151
|
export interface UserIdentity {
|
|
127
152
|
id: string
|
|
128
153
|
user_id: string
|
|
@@ -135,6 +160,33 @@ export interface UserIdentity {
|
|
|
135
160
|
updated_at?: string
|
|
136
161
|
}
|
|
137
162
|
|
|
163
|
+
/**
|
|
164
|
+
* A MFA factor.
|
|
165
|
+
*
|
|
166
|
+
* @see {@link GoTrueMFAApi#enroll}
|
|
167
|
+
* @see {@link GoTrueMFAApi#listFactors}
|
|
168
|
+
* @see {@link GoTrueMFAAdminApi#listFactors}
|
|
169
|
+
*/
|
|
170
|
+
export interface Factor {
|
|
171
|
+
/** ID of the factor. */
|
|
172
|
+
id: string
|
|
173
|
+
|
|
174
|
+
/** Friendly name of the factor, useful to disambiguate between multiple factors. */
|
|
175
|
+
friendly_name?: string
|
|
176
|
+
|
|
177
|
+
/**
|
|
178
|
+
* Type of factor. Only `totp` supported with this version but may change in
|
|
179
|
+
* future versions.
|
|
180
|
+
*/
|
|
181
|
+
factor_type: 'totp' | string
|
|
182
|
+
|
|
183
|
+
/** Factor's status. */
|
|
184
|
+
status: 'verified' | 'unverified'
|
|
185
|
+
|
|
186
|
+
created_at: string
|
|
187
|
+
updated_at: string
|
|
188
|
+
}
|
|
189
|
+
|
|
138
190
|
export interface UserAppMetadata {
|
|
139
191
|
provider?: string
|
|
140
192
|
[key: string]: any
|
|
@@ -165,6 +217,7 @@ export interface User {
|
|
|
165
217
|
role?: string
|
|
166
218
|
updated_at?: string
|
|
167
219
|
identities?: UserIdentity[]
|
|
220
|
+
factors?: Factor[]
|
|
168
221
|
}
|
|
169
222
|
|
|
170
223
|
export interface UserAttributes {
|
|
@@ -258,6 +311,10 @@ export interface Subscription {
|
|
|
258
311
|
unsubscribe: () => void
|
|
259
312
|
}
|
|
260
313
|
|
|
314
|
+
export interface UpdatableFactorAttributes {
|
|
315
|
+
friendlyName: string
|
|
316
|
+
}
|
|
317
|
+
|
|
261
318
|
export type SignUpWithPasswordCredentials =
|
|
262
319
|
| {
|
|
263
320
|
/** The user's email address. */
|
|
@@ -492,6 +549,342 @@ export type GenerateLinkType =
|
|
|
492
549
|
| 'email_change_current'
|
|
493
550
|
| 'email_change_new'
|
|
494
551
|
|
|
552
|
+
/**
|
|
553
|
+
* @experimental
|
|
554
|
+
*/
|
|
555
|
+
export type MFAEnrollParams = {
|
|
556
|
+
factorType: 'totp'
|
|
557
|
+
issuer?: string
|
|
558
|
+
friendlyName?: string
|
|
559
|
+
}
|
|
560
|
+
|
|
561
|
+
/**
|
|
562
|
+
* @experimental
|
|
563
|
+
*/
|
|
564
|
+
export type MFAUnenrollParams = {
|
|
565
|
+
/** ID of the factor being unenrolled. */
|
|
566
|
+
factorId: string
|
|
567
|
+
}
|
|
568
|
+
|
|
569
|
+
/**
|
|
570
|
+
* @experimental
|
|
571
|
+
*/
|
|
572
|
+
export type MFAVerifyParams = {
|
|
573
|
+
/** ID of the factor being verified. */
|
|
574
|
+
factorId: string
|
|
575
|
+
|
|
576
|
+
/** ID of the challenge being verified. */
|
|
577
|
+
challengeId: string
|
|
578
|
+
|
|
579
|
+
/** Verification code provided by the user. */
|
|
580
|
+
code: string
|
|
581
|
+
}
|
|
582
|
+
|
|
583
|
+
/**
|
|
584
|
+
* @experimental
|
|
585
|
+
*/
|
|
586
|
+
export type MFAChallengeParams = {
|
|
587
|
+
/** ID of the factor to be challenged. */
|
|
588
|
+
factorId: string
|
|
589
|
+
}
|
|
590
|
+
|
|
591
|
+
/**
|
|
592
|
+
* @experimental
|
|
593
|
+
*/
|
|
594
|
+
export type AuthMFAVerifyResponse =
|
|
595
|
+
| {
|
|
596
|
+
data: {
|
|
597
|
+
/** New access token (JWT) after successful verification. */
|
|
598
|
+
access_token: string
|
|
599
|
+
|
|
600
|
+
/** Type of token, typically `Bearer`. */
|
|
601
|
+
token_type: string
|
|
602
|
+
|
|
603
|
+
/** Number of seconds in which the access token will expire. */
|
|
604
|
+
expires_in: number
|
|
605
|
+
|
|
606
|
+
/** Refresh token you can use to obtain new access tokens when expired. */
|
|
607
|
+
refresh_token: string
|
|
608
|
+
|
|
609
|
+
/** Updated user profile. */
|
|
610
|
+
user: User
|
|
611
|
+
}
|
|
612
|
+
error: null
|
|
613
|
+
}
|
|
614
|
+
| {
|
|
615
|
+
data: null
|
|
616
|
+
error: AuthError
|
|
617
|
+
}
|
|
618
|
+
|
|
619
|
+
/**
|
|
620
|
+
* @experimental
|
|
621
|
+
*/
|
|
622
|
+
export type AuthMFAEnrollResponse =
|
|
623
|
+
| {
|
|
624
|
+
data: {
|
|
625
|
+
/** ID of the factor that was just enrolled (in an unverified state). */
|
|
626
|
+
id: string
|
|
627
|
+
|
|
628
|
+
/** Type of MFA factor. Only `totp` supported for now. */
|
|
629
|
+
type: 'totp'
|
|
630
|
+
|
|
631
|
+
/** TOTP enrollment information. */
|
|
632
|
+
totp: {
|
|
633
|
+
/** Contains a QR code encoding the authenticator URI. You can
|
|
634
|
+
* convert it to a URL by prepending `data:image/svg+xml;utf-8,` to
|
|
635
|
+
* the value. Avoid logging this value to the console. */
|
|
636
|
+
qr_code: string
|
|
637
|
+
|
|
638
|
+
/** The TOTP secret (also encoded in the QR code). Show this secret
|
|
639
|
+
* in a password-style field to the user, in case they are unable to
|
|
640
|
+
* scan the QR code. Avoid logging this value to the console. */
|
|
641
|
+
secret: string
|
|
642
|
+
|
|
643
|
+
/** The authenticator URI encoded within the QR code, should you need
|
|
644
|
+
* to use it. Avoid loggin this value to the console. */
|
|
645
|
+
uri: string
|
|
646
|
+
}
|
|
647
|
+
}
|
|
648
|
+
error: null
|
|
649
|
+
}
|
|
650
|
+
| {
|
|
651
|
+
data: null
|
|
652
|
+
error: AuthError
|
|
653
|
+
}
|
|
654
|
+
|
|
655
|
+
/**
|
|
656
|
+
* @experimental
|
|
657
|
+
*/
|
|
658
|
+
export type AuthMFAUnenrollResponse =
|
|
659
|
+
| {
|
|
660
|
+
data: {
|
|
661
|
+
/** ID of the factor that was successfully unenrolled. */
|
|
662
|
+
id: string
|
|
663
|
+
}
|
|
664
|
+
error: null
|
|
665
|
+
}
|
|
666
|
+
| { data: null; error: AuthError }
|
|
667
|
+
|
|
668
|
+
/**
|
|
669
|
+
* @experimental
|
|
670
|
+
*/
|
|
671
|
+
export type AuthMFAChallengeResponse =
|
|
672
|
+
| {
|
|
673
|
+
data: {
|
|
674
|
+
/** ID of the newly created challenge. */
|
|
675
|
+
id: string
|
|
676
|
+
|
|
677
|
+
/** Timestamp in UNIX seconds when this challenge will no longer be usable. */
|
|
678
|
+
expires_at: number
|
|
679
|
+
}
|
|
680
|
+
error: null
|
|
681
|
+
}
|
|
682
|
+
| { data: null; error: AuthError }
|
|
683
|
+
|
|
684
|
+
/**
|
|
685
|
+
* @experimental
|
|
686
|
+
*/
|
|
687
|
+
export type AuthMFAListFactorsResponse =
|
|
688
|
+
| {
|
|
689
|
+
data: {
|
|
690
|
+
/** All available factors (verified and unverified). */
|
|
691
|
+
all: Factor[]
|
|
692
|
+
|
|
693
|
+
/** Only verified TOTP factors. (A subset of `all`.) */
|
|
694
|
+
totp: Factor[]
|
|
695
|
+
}
|
|
696
|
+
error: null
|
|
697
|
+
}
|
|
698
|
+
| { data: null; error: AuthError }
|
|
699
|
+
|
|
700
|
+
/**
|
|
701
|
+
* @experimental
|
|
702
|
+
*/
|
|
703
|
+
export type AuthenticatorAssuranceLevels = 'aal1' | 'aal2'
|
|
704
|
+
|
|
705
|
+
/**
|
|
706
|
+
* @experimental
|
|
707
|
+
*/
|
|
708
|
+
export type AuthMFAGetAuthenticatorAssuranceLevelResponse =
|
|
709
|
+
| {
|
|
710
|
+
data: {
|
|
711
|
+
/** Current AAL level of the session. */
|
|
712
|
+
currentLevel: AuthenticatorAssuranceLevels | null
|
|
713
|
+
|
|
714
|
+
/**
|
|
715
|
+
* Next possible AAL level for the session. If the next level is higher
|
|
716
|
+
* than the current one, the user should go through MFA.
|
|
717
|
+
*
|
|
718
|
+
* @see {@link GoTrueMFAApi#challenge}
|
|
719
|
+
*/
|
|
720
|
+
nextLevel: AuthenticatorAssuranceLevels | null
|
|
721
|
+
|
|
722
|
+
/**
|
|
723
|
+
* A list of all authentication methods attached to this session. Use
|
|
724
|
+
* the information here to detect the last time a user verified a
|
|
725
|
+
* factor, for example if implementing a step-up scenario.
|
|
726
|
+
*/
|
|
727
|
+
currentAuthenticationMethods: AMREntry[]
|
|
728
|
+
}
|
|
729
|
+
error: null
|
|
730
|
+
}
|
|
731
|
+
| { data: null; error: AuthError }
|
|
732
|
+
|
|
733
|
+
/**
|
|
734
|
+
* Contains the full multi-factor authentication API.
|
|
735
|
+
*
|
|
736
|
+
* @experimental
|
|
737
|
+
*/
|
|
738
|
+
export interface GoTrueMFAApi {
|
|
739
|
+
/**
|
|
740
|
+
* Starts the enrollment process for a new Multi-Factor Authentication
|
|
741
|
+
* factor. This method creates a new factor in the 'unverified' state.
|
|
742
|
+
* Present the QR code or secret to the user and ask them to add it to their
|
|
743
|
+
* authenticator app. Ask the user to provide you with an authenticator code
|
|
744
|
+
* from their app and verify it by calling challenge and then verify.
|
|
745
|
+
*
|
|
746
|
+
* The first successful verification of an unverified factor activates the
|
|
747
|
+
* factor. All other sessions are logged out and the current one gets an
|
|
748
|
+
* `aal2` authenticator level.
|
|
749
|
+
*
|
|
750
|
+
* @see {@link GoTrueMFAApi#challenge}
|
|
751
|
+
* @see {@link GoTrueMFAApi#verify}
|
|
752
|
+
* @see {@link GoTrueMFAApi#getAuthenticatorAssuranceLevel}
|
|
753
|
+
*
|
|
754
|
+
* @experimental
|
|
755
|
+
*/
|
|
756
|
+
enroll(params: MFAEnrollParams): Promise<AuthMFAEnrollResponse>
|
|
757
|
+
|
|
758
|
+
/**
|
|
759
|
+
* Prepares a challenge used to verify that a user has access to a MFA
|
|
760
|
+
* factor. Provide the challenge ID and verification code by calling
|
|
761
|
+
* {@link GoTrueMFAApi#verify}.
|
|
762
|
+
*
|
|
763
|
+
* @experimental
|
|
764
|
+
*/
|
|
765
|
+
challenge(params: MFAChallengeParams): Promise<AuthMFAChallengeResponse>
|
|
766
|
+
|
|
767
|
+
/**
|
|
768
|
+
* Verifies a verification code against a challenge. The verification code is
|
|
769
|
+
* provided by the user by entering a code seen in their authenticator app.
|
|
770
|
+
*
|
|
771
|
+
* @see {@link GoTrueMFAApi#challenge}
|
|
772
|
+
*
|
|
773
|
+
* @experimental
|
|
774
|
+
*/
|
|
775
|
+
verify(params: MFAVerifyParams): Promise<AuthMFAVerifyResponse>
|
|
776
|
+
|
|
777
|
+
/**
|
|
778
|
+
* Unenroll removes a MFA factor. Unverified factors can safely be ignored
|
|
779
|
+
* and it's not necessary to unenroll them. Unenrolling a verified MFA factor
|
|
780
|
+
* cannot be done from a session with an `aal1` authenticator level.
|
|
781
|
+
*
|
|
782
|
+
* @experimental
|
|
783
|
+
*/
|
|
784
|
+
unenroll(params: MFAUnenrollParams): Promise<AuthMFAUnenrollResponse>
|
|
785
|
+
|
|
786
|
+
/**
|
|
787
|
+
* Returns the list of MFA factors enabled for this user. For most use cases
|
|
788
|
+
* you should consider using {@link
|
|
789
|
+
* GoTrueMFAApi#getAuthenticatorAssuranceLevel}. This uses a cached version
|
|
790
|
+
* of the factors and avoids incurring a network call. If you need to update
|
|
791
|
+
* this list, call {@link GoTrueClient#getUser} first.
|
|
792
|
+
*
|
|
793
|
+
* @see {@link GoTrueMFAApi#enroll}
|
|
794
|
+
* @see {@link GoTrueMFAApi#getAuthenticatorAssuranceLevel}
|
|
795
|
+
* @see {@link GoTrueClient#getUser}
|
|
796
|
+
*
|
|
797
|
+
* @experimental
|
|
798
|
+
*/
|
|
799
|
+
listFactors(): Promise<AuthMFAListFactorsResponse>
|
|
800
|
+
|
|
801
|
+
/**
|
|
802
|
+
* Returns the Authenticator Assurance Level (AAL) for the active session.
|
|
803
|
+
*
|
|
804
|
+
* - `aal1` (or `null`) means that the user's identity has been verified only
|
|
805
|
+
* with a conventional login (email+password, OTP, magic link, social login,
|
|
806
|
+
* etc.).
|
|
807
|
+
* - `aal2` means that the user's identity has been verified both with a conventional login and at least one MFA factor.
|
|
808
|
+
*
|
|
809
|
+
* Although this method returns a promise, it's fairly quick (microseconds)
|
|
810
|
+
* and rarely uses the network. You can use this to check whether the current
|
|
811
|
+
* user needs to be shown a screen to verify their MFA factors.
|
|
812
|
+
*
|
|
813
|
+
* @experimental
|
|
814
|
+
*/
|
|
815
|
+
getAuthenticatorAssuranceLevel(): Promise<AuthMFAGetAuthenticatorAssuranceLevelResponse>
|
|
816
|
+
}
|
|
817
|
+
|
|
818
|
+
/**
|
|
819
|
+
* @expermental
|
|
820
|
+
*/
|
|
821
|
+
export type AuthMFAAdminDeleteFactorResponse =
|
|
822
|
+
| {
|
|
823
|
+
data: {
|
|
824
|
+
/** ID of the factor that was successfully deleted. */
|
|
825
|
+
id: string
|
|
826
|
+
}
|
|
827
|
+
error: null
|
|
828
|
+
}
|
|
829
|
+
| { data: null; error: AuthError }
|
|
830
|
+
|
|
831
|
+
/**
|
|
832
|
+
* @expermental
|
|
833
|
+
*/
|
|
834
|
+
export type AuthMFAAdminDeleteFactorParams = {
|
|
835
|
+
/** ID of the MFA factor to delete. */
|
|
836
|
+
id: string
|
|
837
|
+
|
|
838
|
+
/** ID of the user whose factor is being deleted. */
|
|
839
|
+
userId: string
|
|
840
|
+
}
|
|
841
|
+
|
|
842
|
+
/**
|
|
843
|
+
* @expermental
|
|
844
|
+
*/
|
|
845
|
+
export type AuthMFAAdminListFactorsResponse =
|
|
846
|
+
| {
|
|
847
|
+
data: {
|
|
848
|
+
/** All factors attached to the user. */
|
|
849
|
+
factors: Factor[]
|
|
850
|
+
}
|
|
851
|
+
error: null
|
|
852
|
+
}
|
|
853
|
+
| { data: null; error: AuthError }
|
|
854
|
+
|
|
855
|
+
/**
|
|
856
|
+
* @expermental
|
|
857
|
+
*/
|
|
858
|
+
export type AuthMFAAdminListFactorsParams = {
|
|
859
|
+
/** ID of the user for which to list all MFA factors. */
|
|
860
|
+
userId: string
|
|
861
|
+
}
|
|
862
|
+
|
|
863
|
+
/**
|
|
864
|
+
* Contains the full multi-factor authentication administration API.
|
|
865
|
+
*
|
|
866
|
+
* @expermental
|
|
867
|
+
*/
|
|
868
|
+
export interface GoTrueAdminMFAApi {
|
|
869
|
+
/**
|
|
870
|
+
* Lists all factors attached to a user.
|
|
871
|
+
*
|
|
872
|
+
* @experimental
|
|
873
|
+
*/
|
|
874
|
+
listFactors(params: AuthMFAAdminListFactorsParams): Promise<AuthMFAAdminListFactorsResponse>
|
|
875
|
+
|
|
876
|
+
/**
|
|
877
|
+
* Deletes a factor on a user. This will log the user out of all active
|
|
878
|
+
* sessions (if the deleted factor was verified). There's no need to delete
|
|
879
|
+
* unverified factors.
|
|
880
|
+
*
|
|
881
|
+
* @see {@link GoTrueMFAApi#unenroll}
|
|
882
|
+
*
|
|
883
|
+
* @expermental
|
|
884
|
+
*/
|
|
885
|
+
deleteFactor(params: AuthMFAAdminDeleteFactorParams): Promise<AuthMFAAdminDeleteFactorResponse>
|
|
886
|
+
}
|
|
887
|
+
|
|
495
888
|
type AnyFunction = (...args: any[]) => any
|
|
496
889
|
type MaybePromisify<T> = T | Promise<T>
|
|
497
890
|
|
package/src/lib/version.ts
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
1
|
// Generated by genversion.
|
|
2
|
-
export const version = '2.0
|
|
2
|
+
export const version = '2.1.0'
|