@supabase/gotrue-js 2.42.0 → 2.43.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/dist/main/GoTrueClient.d.ts +13 -0
- package/dist/main/GoTrueClient.d.ts.map +1 -1
- package/dist/main/GoTrueClient.js +280 -221
- package/dist/main/GoTrueClient.js.map +1 -1
- package/dist/main/lib/helpers.d.ts +23 -0
- package/dist/main/lib/helpers.d.ts.map +1 -1
- package/dist/main/lib/helpers.js +94 -1
- package/dist/main/lib/helpers.js.map +1 -1
- package/dist/main/lib/version.d.ts +1 -1
- package/dist/main/lib/version.js +1 -1
- package/dist/module/GoTrueClient.d.ts +13 -0
- package/dist/module/GoTrueClient.d.ts.map +1 -1
- package/dist/module/GoTrueClient.js +281 -222
- package/dist/module/GoTrueClient.js.map +1 -1
- package/dist/module/lib/helpers.d.ts +23 -0
- package/dist/module/lib/helpers.d.ts.map +1 -1
- package/dist/module/lib/helpers.js +91 -0
- package/dist/module/lib/helpers.js.map +1 -1
- package/dist/module/lib/version.d.ts +1 -1
- package/dist/module/lib/version.js +1 -1
- package/package.json +1 -1
- package/src/GoTrueClient.ts +337 -250
- package/src/lib/helpers.ts +111 -0
- package/src/lib/version.ts +1 -1
|
@@ -109,10 +109,10 @@ class GoTrueClient {
|
|
|
109
109
|
* manually when checking for an error from an auth redirect (oauth, magiclink, password recovery, etc).
|
|
110
110
|
*/
|
|
111
111
|
initialize() {
|
|
112
|
-
if (
|
|
113
|
-
this.initializePromise
|
|
112
|
+
if (this.initializePromise) {
|
|
113
|
+
return this.initializePromise;
|
|
114
114
|
}
|
|
115
|
-
return this.
|
|
115
|
+
return this._initialize();
|
|
116
116
|
}
|
|
117
117
|
/**
|
|
118
118
|
* IMPORTANT:
|
|
@@ -122,49 +122,52 @@ class GoTrueClient {
|
|
|
122
122
|
*/
|
|
123
123
|
async _initialize() {
|
|
124
124
|
if (this.initializePromise) {
|
|
125
|
-
|
|
125
|
+
throw new Error('Double call of #_initialize()');
|
|
126
126
|
}
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
const { session, redirectType } = data;
|
|
140
|
-
this._debug('#_initialize()', 'detected session in URL', session, 'redirect type', redirectType);
|
|
141
|
-
await this._saveSession(session);
|
|
142
|
-
setTimeout(async () => {
|
|
143
|
-
if (redirectType === 'recovery') {
|
|
144
|
-
await this._notifyAllSubscribers('PASSWORD_RECOVERY', session);
|
|
145
|
-
}
|
|
146
|
-
else {
|
|
147
|
-
await this._notifyAllSubscribers('SIGNED_IN', session);
|
|
127
|
+
this.initializePromise = (0, helpers_1.stackGuard)('_initialize', async () => {
|
|
128
|
+
try {
|
|
129
|
+
const isPKCEFlow = (0, helpers_1.isBrowser)() ? await this._isPKCEFlow() : false;
|
|
130
|
+
this._debug('#_initialize()', 'begin', 'is PKCE flow', isPKCEFlow);
|
|
131
|
+
if (isPKCEFlow || (this.detectSessionInUrl && this._isImplicitGrantFlow())) {
|
|
132
|
+
const { data, error } = await this._getSessionFromUrl(isPKCEFlow);
|
|
133
|
+
if (error) {
|
|
134
|
+
this._debug('#_initialize()', 'error detecting session from URL', error);
|
|
135
|
+
// failed login attempt via url,
|
|
136
|
+
// remove old session as in verifyOtp, signUp and signInWith*
|
|
137
|
+
await this._removeSession();
|
|
138
|
+
return { error };
|
|
148
139
|
}
|
|
149
|
-
|
|
140
|
+
const { session, redirectType } = data;
|
|
141
|
+
this._debug('#_initialize()', 'detected session in URL', session, 'redirect type', redirectType);
|
|
142
|
+
await this._saveSession(session);
|
|
143
|
+
setTimeout(async () => {
|
|
144
|
+
if (redirectType === 'recovery') {
|
|
145
|
+
await this._notifyAllSubscribers('PASSWORD_RECOVERY', session);
|
|
146
|
+
}
|
|
147
|
+
else {
|
|
148
|
+
await this._notifyAllSubscribers('SIGNED_IN', session);
|
|
149
|
+
}
|
|
150
|
+
}, 0);
|
|
151
|
+
return { error: null };
|
|
152
|
+
}
|
|
153
|
+
// no login attempt via callback url try to recover session from storage
|
|
154
|
+
await this._recoverAndRefresh();
|
|
150
155
|
return { error: null };
|
|
151
156
|
}
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
157
|
+
catch (error) {
|
|
158
|
+
if ((0, errors_1.isAuthError)(error)) {
|
|
159
|
+
return { error };
|
|
160
|
+
}
|
|
161
|
+
return {
|
|
162
|
+
error: new errors_1.AuthUnknownError('Unexpected error during initialization', error),
|
|
163
|
+
};
|
|
159
164
|
}
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
this._debug('#_initialize()', 'end');
|
|
167
|
-
}
|
|
165
|
+
finally {
|
|
166
|
+
await this._handleVisibilityChange();
|
|
167
|
+
this._debug('#_initialize()', 'end');
|
|
168
|
+
}
|
|
169
|
+
});
|
|
170
|
+
return await this.initializePromise;
|
|
168
171
|
}
|
|
169
172
|
/**
|
|
170
173
|
* Creates a new user.
|
|
@@ -526,16 +529,18 @@ class GoTrueClient {
|
|
|
526
529
|
*/
|
|
527
530
|
async reauthenticate() {
|
|
528
531
|
try {
|
|
529
|
-
|
|
530
|
-
|
|
531
|
-
|
|
532
|
-
|
|
533
|
-
|
|
534
|
-
|
|
535
|
-
|
|
536
|
-
|
|
532
|
+
return await this._useSession(async (result) => {
|
|
533
|
+
const { data: { session }, error: sessionError, } = result;
|
|
534
|
+
if (sessionError)
|
|
535
|
+
throw sessionError;
|
|
536
|
+
if (!session)
|
|
537
|
+
throw new errors_1.AuthSessionMissingError();
|
|
538
|
+
const { error } = await (0, fetch_1._request)(this.fetch, 'GET', `${this.url}/reauthenticate`, {
|
|
539
|
+
headers: this.headers,
|
|
540
|
+
jwt: session.access_token,
|
|
541
|
+
});
|
|
542
|
+
return { data: { user: null, session: null }, error };
|
|
537
543
|
});
|
|
538
|
-
return { data: { user: null, session: null }, error };
|
|
539
544
|
}
|
|
540
545
|
catch (error) {
|
|
541
546
|
if ((0, errors_1.isAuthError)(error)) {
|
|
@@ -592,10 +597,42 @@ class GoTrueClient {
|
|
|
592
597
|
* The session returned can be null if the session is not detected which can happen in the event a user is not signed-in or has logged out.
|
|
593
598
|
*/
|
|
594
599
|
async getSession() {
|
|
600
|
+
return this._useSession(async (result) => {
|
|
601
|
+
return result;
|
|
602
|
+
});
|
|
603
|
+
}
|
|
604
|
+
/**
|
|
605
|
+
* Use instead of {@link #getSession} inside the library. It is
|
|
606
|
+
* semantically usually what you want, as getting a session involves some
|
|
607
|
+
* processing afterwards that requires only one client operating on the
|
|
608
|
+
* session at once across multiple tabs or processes.
|
|
609
|
+
*/
|
|
610
|
+
async _useSession(fn) {
|
|
611
|
+
return await (0, helpers_1.stackGuard)('_useSession', async () => {
|
|
612
|
+
// the use of __loadSession here is the only correct use of the function!
|
|
613
|
+
const result = await this.__loadSession();
|
|
614
|
+
return await fn(result);
|
|
615
|
+
});
|
|
616
|
+
}
|
|
617
|
+
/**
|
|
618
|
+
* NEVER USE DIRECTLY!
|
|
619
|
+
*
|
|
620
|
+
* Always use {@link #_useSession}.
|
|
621
|
+
*/
|
|
622
|
+
async __loadSession() {
|
|
623
|
+
this._debug('#__loadSession()', 'begin');
|
|
624
|
+
if (this.logDebugMessages && !(0, helpers_1.isInStackGuard)('_useSession')) {
|
|
625
|
+
throw new Error('Please use #_useSession()');
|
|
626
|
+
}
|
|
595
627
|
// make sure we've read the session from the url if there is one
|
|
596
628
|
// save to just await, as long we make sure _initialize() never throws
|
|
597
|
-
|
|
598
|
-
|
|
629
|
+
if (!(0, helpers_1.isInStackGuard)('_initialize')) {
|
|
630
|
+
// only wait when not called from within #_initialize() since it's
|
|
631
|
+
// waiting for itself. one such pathway is #_initialize() ->
|
|
632
|
+
// #_handleVisibilityChange() -> #_onVisbilityChanged() ->
|
|
633
|
+
// #_loadSession().
|
|
634
|
+
await this.initializePromise;
|
|
635
|
+
}
|
|
599
636
|
try {
|
|
600
637
|
let currentSession = null;
|
|
601
638
|
if (this.persistSession) {
|
|
@@ -621,7 +658,7 @@ class GoTrueClient {
|
|
|
621
658
|
const hasExpired = currentSession.expires_at
|
|
622
659
|
? currentSession.expires_at <= Date.now() / 1000
|
|
623
660
|
: false;
|
|
624
|
-
this._debug('#
|
|
661
|
+
this._debug('#__loadSession()', `session has${hasExpired ? '' : ' not'} expired`, 'expires_at', currentSession.expires_at);
|
|
625
662
|
if (!hasExpired) {
|
|
626
663
|
return { data: { session: currentSession }, error: null };
|
|
627
664
|
}
|
|
@@ -632,7 +669,7 @@ class GoTrueClient {
|
|
|
632
669
|
return { data: { session }, error: null };
|
|
633
670
|
}
|
|
634
671
|
finally {
|
|
635
|
-
this._debug('#
|
|
672
|
+
this._debug('#__loadSession()', 'end');
|
|
636
673
|
}
|
|
637
674
|
}
|
|
638
675
|
/**
|
|
@@ -640,20 +677,22 @@ class GoTrueClient {
|
|
|
640
677
|
* @param jwt Takes in an optional access token jwt. If no jwt is provided, getUser() will attempt to get the jwt from the current session.
|
|
641
678
|
*/
|
|
642
679
|
async getUser(jwt) {
|
|
643
|
-
var _a, _b;
|
|
644
680
|
try {
|
|
645
|
-
|
|
646
|
-
|
|
647
|
-
if (
|
|
648
|
-
|
|
681
|
+
return await this._useSession(async (result) => {
|
|
682
|
+
var _a, _b;
|
|
683
|
+
if (!jwt) {
|
|
684
|
+
const { data, error } = result;
|
|
685
|
+
if (error) {
|
|
686
|
+
throw error;
|
|
687
|
+
}
|
|
688
|
+
// Default to Authorization header if there is no existing session
|
|
689
|
+
jwt = (_b = (_a = data.session) === null || _a === void 0 ? void 0 : _a.access_token) !== null && _b !== void 0 ? _b : undefined;
|
|
649
690
|
}
|
|
650
|
-
|
|
651
|
-
|
|
652
|
-
|
|
653
|
-
|
|
654
|
-
|
|
655
|
-
jwt: jwt,
|
|
656
|
-
xform: fetch_1._userResponse,
|
|
691
|
+
return await (0, fetch_1._request)(this.fetch, 'GET', `${this.url}/user`, {
|
|
692
|
+
headers: this.headers,
|
|
693
|
+
jwt: jwt,
|
|
694
|
+
xform: fetch_1._userResponse,
|
|
695
|
+
});
|
|
657
696
|
});
|
|
658
697
|
}
|
|
659
698
|
catch (error) {
|
|
@@ -668,27 +707,29 @@ class GoTrueClient {
|
|
|
668
707
|
*/
|
|
669
708
|
async updateUser(attributes, options = {}) {
|
|
670
709
|
try {
|
|
671
|
-
|
|
672
|
-
|
|
673
|
-
|
|
674
|
-
|
|
675
|
-
|
|
676
|
-
|
|
677
|
-
|
|
678
|
-
|
|
679
|
-
|
|
680
|
-
|
|
681
|
-
|
|
682
|
-
|
|
683
|
-
|
|
684
|
-
|
|
710
|
+
return await this._useSession(async (result) => {
|
|
711
|
+
const { data: sessionData, error: sessionError } = result;
|
|
712
|
+
if (sessionError) {
|
|
713
|
+
throw sessionError;
|
|
714
|
+
}
|
|
715
|
+
if (!sessionData.session) {
|
|
716
|
+
throw new errors_1.AuthSessionMissingError();
|
|
717
|
+
}
|
|
718
|
+
const session = sessionData.session;
|
|
719
|
+
const { data, error: userError } = await (0, fetch_1._request)(this.fetch, 'PUT', `${this.url}/user`, {
|
|
720
|
+
headers: this.headers,
|
|
721
|
+
redirectTo: options === null || options === void 0 ? void 0 : options.emailRedirectTo,
|
|
722
|
+
body: attributes,
|
|
723
|
+
jwt: session.access_token,
|
|
724
|
+
xform: fetch_1._userResponse,
|
|
725
|
+
});
|
|
726
|
+
if (userError)
|
|
727
|
+
throw userError;
|
|
728
|
+
session.user = data.user;
|
|
729
|
+
await this._saveSession(session);
|
|
730
|
+
await this._notifyAllSubscribers('USER_UPDATED', session);
|
|
731
|
+
return { data: { user: session.user }, error: null };
|
|
685
732
|
});
|
|
686
|
-
if (userError)
|
|
687
|
-
throw userError;
|
|
688
|
-
session.user = data.user;
|
|
689
|
-
await this._saveSession(session);
|
|
690
|
-
await this._notifyAllSubscribers('USER_UPDATED', session);
|
|
691
|
-
return { data: { user: session.user }, error: null };
|
|
692
733
|
}
|
|
693
734
|
catch (error) {
|
|
694
735
|
if ((0, errors_1.isAuthError)(error)) {
|
|
@@ -764,26 +805,28 @@ class GoTrueClient {
|
|
|
764
805
|
* @param currentSession The current session. If passed in, it must contain a refresh token.
|
|
765
806
|
*/
|
|
766
807
|
async refreshSession(currentSession) {
|
|
767
|
-
var _a;
|
|
768
808
|
try {
|
|
769
|
-
|
|
770
|
-
|
|
809
|
+
return await this._useSession(async (result) => {
|
|
810
|
+
var _a;
|
|
811
|
+
if (!currentSession) {
|
|
812
|
+
const { data, error } = result;
|
|
813
|
+
if (error) {
|
|
814
|
+
throw error;
|
|
815
|
+
}
|
|
816
|
+
currentSession = (_a = data.session) !== null && _a !== void 0 ? _a : undefined;
|
|
817
|
+
}
|
|
818
|
+
if (!(currentSession === null || currentSession === void 0 ? void 0 : currentSession.refresh_token)) {
|
|
819
|
+
throw new errors_1.AuthSessionMissingError();
|
|
820
|
+
}
|
|
821
|
+
const { session, error } = await this._callRefreshToken(currentSession.refresh_token);
|
|
771
822
|
if (error) {
|
|
772
|
-
|
|
823
|
+
return { data: { user: null, session: null }, error: error };
|
|
773
824
|
}
|
|
774
|
-
|
|
775
|
-
|
|
776
|
-
|
|
777
|
-
|
|
778
|
-
}
|
|
779
|
-
const { session, error } = await this._callRefreshToken(currentSession.refresh_token);
|
|
780
|
-
if (error) {
|
|
781
|
-
return { data: { user: null, session: null }, error: error };
|
|
782
|
-
}
|
|
783
|
-
if (!session) {
|
|
784
|
-
return { data: { user: null, session: null }, error: null };
|
|
785
|
-
}
|
|
786
|
-
return { data: { user: session.user, session }, error: null };
|
|
825
|
+
if (!session) {
|
|
826
|
+
return { data: { user: null, session: null }, error: null };
|
|
827
|
+
}
|
|
828
|
+
return { data: { user: session.user, session }, error: null };
|
|
829
|
+
});
|
|
787
830
|
}
|
|
788
831
|
catch (error) {
|
|
789
832
|
if ((0, errors_1.isAuthError)(error)) {
|
|
@@ -897,28 +940,30 @@ class GoTrueClient {
|
|
|
897
940
|
* If using others scope, no `SIGNED_OUT` event is fired!
|
|
898
941
|
*/
|
|
899
942
|
async signOut({ scope } = { scope: 'global' }) {
|
|
900
|
-
|
|
901
|
-
|
|
902
|
-
|
|
903
|
-
|
|
904
|
-
|
|
905
|
-
|
|
906
|
-
|
|
907
|
-
|
|
908
|
-
|
|
909
|
-
|
|
910
|
-
|
|
911
|
-
|
|
912
|
-
|
|
943
|
+
return await this._useSession(async (result) => {
|
|
944
|
+
var _a;
|
|
945
|
+
const { data, error: sessionError } = result;
|
|
946
|
+
if (sessionError) {
|
|
947
|
+
return { error: sessionError };
|
|
948
|
+
}
|
|
949
|
+
const accessToken = (_a = data.session) === null || _a === void 0 ? void 0 : _a.access_token;
|
|
950
|
+
if (accessToken) {
|
|
951
|
+
const { error } = await this.admin.signOut(accessToken, scope);
|
|
952
|
+
if (error) {
|
|
953
|
+
// ignore 404s since user might not exist anymore
|
|
954
|
+
// ignore 401s since an invalid or expired JWT should sign out the current session
|
|
955
|
+
if (!((0, errors_1.isAuthApiError)(error) && (error.status === 404 || error.status === 401))) {
|
|
956
|
+
return { error };
|
|
957
|
+
}
|
|
913
958
|
}
|
|
914
959
|
}
|
|
915
|
-
|
|
916
|
-
|
|
917
|
-
|
|
918
|
-
|
|
919
|
-
|
|
920
|
-
|
|
921
|
-
|
|
960
|
+
if (scope !== 'others') {
|
|
961
|
+
await this._removeSession();
|
|
962
|
+
await (0, helpers_1.removeItemAsync)(this.storage, `${this.storageKey}-code-verifier`);
|
|
963
|
+
await this._notifyAllSubscribers('SIGNED_OUT', null);
|
|
964
|
+
}
|
|
965
|
+
return { error: null };
|
|
966
|
+
});
|
|
922
967
|
}
|
|
923
968
|
/**
|
|
924
969
|
* Receive a notification every time an auth event happens.
|
|
@@ -940,19 +985,21 @@ class GoTrueClient {
|
|
|
940
985
|
return { data: { subscription } };
|
|
941
986
|
}
|
|
942
987
|
async _emitInitialSession(id) {
|
|
943
|
-
|
|
944
|
-
|
|
945
|
-
|
|
946
|
-
|
|
947
|
-
|
|
948
|
-
|
|
949
|
-
|
|
950
|
-
|
|
951
|
-
|
|
952
|
-
|
|
953
|
-
|
|
954
|
-
|
|
955
|
-
|
|
988
|
+
return await this._useSession(async (result) => {
|
|
989
|
+
var _a, _b;
|
|
990
|
+
try {
|
|
991
|
+
const { data: { session }, error, } = result;
|
|
992
|
+
if (error)
|
|
993
|
+
throw error;
|
|
994
|
+
await ((_a = this.stateChangeEmitters.get(id)) === null || _a === void 0 ? void 0 : _a.callback('INITIAL_SESSION', session));
|
|
995
|
+
this._debug('INITIAL_SESSION', 'callback id', id, 'session', session);
|
|
996
|
+
}
|
|
997
|
+
catch (err) {
|
|
998
|
+
await ((_b = this.stateChangeEmitters.get(id)) === null || _b === void 0 ? void 0 : _b.callback('INITIAL_SESSION', null));
|
|
999
|
+
this._debug('INITIAL_SESSION', 'callback id', id, 'error', err);
|
|
1000
|
+
console.error(err);
|
|
1001
|
+
}
|
|
1002
|
+
});
|
|
956
1003
|
}
|
|
957
1004
|
/**
|
|
958
1005
|
* Sends a password reset request to an email address.
|
|
@@ -1292,17 +1339,19 @@ class GoTrueClient {
|
|
|
1292
1339
|
try {
|
|
1293
1340
|
const now = Date.now();
|
|
1294
1341
|
try {
|
|
1295
|
-
|
|
1296
|
-
|
|
1297
|
-
|
|
1298
|
-
|
|
1299
|
-
|
|
1300
|
-
|
|
1301
|
-
|
|
1302
|
-
|
|
1303
|
-
|
|
1304
|
-
|
|
1305
|
-
|
|
1342
|
+
return await this._useSession(async (result) => {
|
|
1343
|
+
const { data: { session }, } = result;
|
|
1344
|
+
if (!session || !session.refresh_token || !session.expires_at) {
|
|
1345
|
+
this._debug('#_autoRefreshTokenTick()', 'no session');
|
|
1346
|
+
return;
|
|
1347
|
+
}
|
|
1348
|
+
// session will expire in this many ticks (or has already expired if <= 0)
|
|
1349
|
+
const expiresInTicks = Math.floor((session.expires_at * 1000 - now) / AUTO_REFRESH_TICK_DURATION);
|
|
1350
|
+
this._debug('#_autoRefreshTokenTick()', `access token expires in ${expiresInTicks} ticks, a tick lasts ${AUTO_REFRESH_TICK_DURATION}ms, refresh threshold is ${AUTO_REFRESH_TICK_THRESHOLD} ticks`);
|
|
1351
|
+
if (expiresInTicks <= AUTO_REFRESH_TICK_THRESHOLD) {
|
|
1352
|
+
await this._callRefreshToken(session.refresh_token);
|
|
1353
|
+
}
|
|
1354
|
+
});
|
|
1306
1355
|
}
|
|
1307
1356
|
catch (e) {
|
|
1308
1357
|
console.error('Auto refresh tick failed with error. This is likely a transient error.', e);
|
|
@@ -1394,15 +1443,17 @@ class GoTrueClient {
|
|
|
1394
1443
|
return `${this.url}/authorize?${urlParams.join('&')}`;
|
|
1395
1444
|
}
|
|
1396
1445
|
async _unenroll(params) {
|
|
1397
|
-
var _a;
|
|
1398
1446
|
try {
|
|
1399
|
-
|
|
1400
|
-
|
|
1401
|
-
|
|
1402
|
-
|
|
1403
|
-
|
|
1404
|
-
|
|
1405
|
-
|
|
1447
|
+
return await this._useSession(async (result) => {
|
|
1448
|
+
var _a;
|
|
1449
|
+
const { data: sessionData, error: sessionError } = result;
|
|
1450
|
+
if (sessionError) {
|
|
1451
|
+
return { data: null, error: sessionError };
|
|
1452
|
+
}
|
|
1453
|
+
return await (0, fetch_1._request)(this.fetch, 'DELETE', `${this.url}/factors/${params.factorId}`, {
|
|
1454
|
+
headers: this.headers,
|
|
1455
|
+
jwt: (_a = sessionData === null || sessionData === void 0 ? void 0 : sessionData.session) === null || _a === void 0 ? void 0 : _a.access_token,
|
|
1456
|
+
});
|
|
1406
1457
|
});
|
|
1407
1458
|
}
|
|
1408
1459
|
catch (error) {
|
|
@@ -1416,28 +1467,30 @@ class GoTrueClient {
|
|
|
1416
1467
|
* {@see GoTrueMFAApi#enroll}
|
|
1417
1468
|
*/
|
|
1418
1469
|
async _enroll(params) {
|
|
1419
|
-
var _a, _b;
|
|
1420
1470
|
try {
|
|
1421
|
-
|
|
1422
|
-
|
|
1423
|
-
|
|
1424
|
-
|
|
1425
|
-
|
|
1426
|
-
|
|
1427
|
-
|
|
1428
|
-
|
|
1429
|
-
|
|
1430
|
-
|
|
1431
|
-
|
|
1432
|
-
|
|
1471
|
+
return await this._useSession(async (result) => {
|
|
1472
|
+
var _a, _b;
|
|
1473
|
+
const { data: sessionData, error: sessionError } = result;
|
|
1474
|
+
if (sessionError) {
|
|
1475
|
+
return { data: null, error: sessionError };
|
|
1476
|
+
}
|
|
1477
|
+
const { data, error } = await (0, fetch_1._request)(this.fetch, 'POST', `${this.url}/factors`, {
|
|
1478
|
+
body: {
|
|
1479
|
+
friendly_name: params.friendlyName,
|
|
1480
|
+
factor_type: params.factorType,
|
|
1481
|
+
issuer: params.issuer,
|
|
1482
|
+
},
|
|
1483
|
+
headers: this.headers,
|
|
1484
|
+
jwt: (_a = sessionData === null || sessionData === void 0 ? void 0 : sessionData.session) === null || _a === void 0 ? void 0 : _a.access_token,
|
|
1485
|
+
});
|
|
1486
|
+
if (error) {
|
|
1487
|
+
return { data: null, error };
|
|
1488
|
+
}
|
|
1489
|
+
if ((_b = data === null || data === void 0 ? void 0 : data.totp) === null || _b === void 0 ? void 0 : _b.qr_code) {
|
|
1490
|
+
data.totp.qr_code = `data:image/svg+xml;utf-8,${data.totp.qr_code}`;
|
|
1491
|
+
}
|
|
1492
|
+
return { data, error: null };
|
|
1433
1493
|
});
|
|
1434
|
-
if (error) {
|
|
1435
|
-
return { data: null, error };
|
|
1436
|
-
}
|
|
1437
|
-
if ((_b = data === null || data === void 0 ? void 0 : data.totp) === null || _b === void 0 ? void 0 : _b.qr_code) {
|
|
1438
|
-
data.totp.qr_code = `data:image/svg+xml;utf-8,${data.totp.qr_code}`;
|
|
1439
|
-
}
|
|
1440
|
-
return { data, error: null };
|
|
1441
1494
|
}
|
|
1442
1495
|
catch (error) {
|
|
1443
1496
|
if ((0, errors_1.isAuthError)(error)) {
|
|
@@ -1450,23 +1503,25 @@ class GoTrueClient {
|
|
|
1450
1503
|
* {@see GoTrueMFAApi#verify}
|
|
1451
1504
|
*/
|
|
1452
1505
|
async _verify(params) {
|
|
1453
|
-
var _a;
|
|
1454
1506
|
try {
|
|
1455
|
-
|
|
1456
|
-
|
|
1457
|
-
|
|
1458
|
-
|
|
1459
|
-
|
|
1460
|
-
|
|
1461
|
-
|
|
1462
|
-
|
|
1507
|
+
return await this._useSession(async (result) => {
|
|
1508
|
+
var _a;
|
|
1509
|
+
const { data: sessionData, error: sessionError } = result;
|
|
1510
|
+
if (sessionError) {
|
|
1511
|
+
return { data: null, error: sessionError };
|
|
1512
|
+
}
|
|
1513
|
+
const { data, error } = await (0, fetch_1._request)(this.fetch, 'POST', `${this.url}/factors/${params.factorId}/verify`, {
|
|
1514
|
+
body: { code: params.code, challenge_id: params.challengeId },
|
|
1515
|
+
headers: this.headers,
|
|
1516
|
+
jwt: (_a = sessionData === null || sessionData === void 0 ? void 0 : sessionData.session) === null || _a === void 0 ? void 0 : _a.access_token,
|
|
1517
|
+
});
|
|
1518
|
+
if (error) {
|
|
1519
|
+
return { data: null, error };
|
|
1520
|
+
}
|
|
1521
|
+
await this._saveSession(Object.assign({ expires_at: Math.round(Date.now() / 1000) + data.expires_in }, data));
|
|
1522
|
+
await this._notifyAllSubscribers('MFA_CHALLENGE_VERIFIED', data);
|
|
1523
|
+
return { data, error };
|
|
1463
1524
|
});
|
|
1464
|
-
if (error) {
|
|
1465
|
-
return { data: null, error };
|
|
1466
|
-
}
|
|
1467
|
-
await this._saveSession(Object.assign({ expires_at: Math.round(Date.now() / 1000) + data.expires_in }, data));
|
|
1468
|
-
await this._notifyAllSubscribers('MFA_CHALLENGE_VERIFIED', data);
|
|
1469
|
-
return { data, error };
|
|
1470
1525
|
}
|
|
1471
1526
|
catch (error) {
|
|
1472
1527
|
if ((0, errors_1.isAuthError)(error)) {
|
|
@@ -1479,15 +1534,17 @@ class GoTrueClient {
|
|
|
1479
1534
|
* {@see GoTrueMFAApi#challenge}
|
|
1480
1535
|
*/
|
|
1481
1536
|
async _challenge(params) {
|
|
1482
|
-
var _a;
|
|
1483
1537
|
try {
|
|
1484
|
-
|
|
1485
|
-
|
|
1486
|
-
|
|
1487
|
-
|
|
1488
|
-
|
|
1489
|
-
|
|
1490
|
-
|
|
1538
|
+
return await this._useSession(async (result) => {
|
|
1539
|
+
var _a;
|
|
1540
|
+
const { data: sessionData, error: sessionError } = result;
|
|
1541
|
+
if (sessionError) {
|
|
1542
|
+
return { data: null, error: sessionError };
|
|
1543
|
+
}
|
|
1544
|
+
return await (0, fetch_1._request)(this.fetch, 'POST', `${this.url}/factors/${params.factorId}/challenge`, {
|
|
1545
|
+
headers: this.headers,
|
|
1546
|
+
jwt: (_a = sessionData === null || sessionData === void 0 ? void 0 : sessionData.session) === null || _a === void 0 ? void 0 : _a.access_token,
|
|
1547
|
+
});
|
|
1491
1548
|
});
|
|
1492
1549
|
}
|
|
1493
1550
|
catch (error) {
|
|
@@ -1535,29 +1592,31 @@ class GoTrueClient {
|
|
|
1535
1592
|
* {@see GoTrueMFAApi#getAuthenticatorAssuranceLevel}
|
|
1536
1593
|
*/
|
|
1537
1594
|
async _getAuthenticatorAssuranceLevel() {
|
|
1538
|
-
|
|
1539
|
-
|
|
1540
|
-
|
|
1541
|
-
|
|
1542
|
-
|
|
1543
|
-
|
|
1544
|
-
|
|
1545
|
-
|
|
1546
|
-
|
|
1547
|
-
|
|
1548
|
-
|
|
1549
|
-
|
|
1550
|
-
|
|
1551
|
-
|
|
1552
|
-
|
|
1553
|
-
|
|
1554
|
-
|
|
1555
|
-
|
|
1556
|
-
|
|
1557
|
-
|
|
1558
|
-
|
|
1559
|
-
|
|
1560
|
-
|
|
1595
|
+
return await this._useSession(async (result) => {
|
|
1596
|
+
var _a, _b;
|
|
1597
|
+
const { data: { session }, error: sessionError, } = result;
|
|
1598
|
+
if (sessionError) {
|
|
1599
|
+
return { data: null, error: sessionError };
|
|
1600
|
+
}
|
|
1601
|
+
if (!session) {
|
|
1602
|
+
return {
|
|
1603
|
+
data: { currentLevel: null, nextLevel: null, currentAuthenticationMethods: [] },
|
|
1604
|
+
error: null,
|
|
1605
|
+
};
|
|
1606
|
+
}
|
|
1607
|
+
const payload = this._decodeJWT(session.access_token);
|
|
1608
|
+
let currentLevel = null;
|
|
1609
|
+
if (payload.aal) {
|
|
1610
|
+
currentLevel = payload.aal;
|
|
1611
|
+
}
|
|
1612
|
+
let nextLevel = currentLevel;
|
|
1613
|
+
const verifiedFactors = (_b = (_a = session.user.factors) === null || _a === void 0 ? void 0 : _a.filter((factor) => factor.status === 'verified')) !== null && _b !== void 0 ? _b : [];
|
|
1614
|
+
if (verifiedFactors.length > 0) {
|
|
1615
|
+
nextLevel = 'aal2';
|
|
1616
|
+
}
|
|
1617
|
+
const currentAuthenticationMethods = payload.amr || [];
|
|
1618
|
+
return { data: { currentLevel, nextLevel, currentAuthenticationMethods }, error: null };
|
|
1619
|
+
});
|
|
1561
1620
|
}
|
|
1562
1621
|
}
|
|
1563
1622
|
exports.default = GoTrueClient;
|