@supabase/gotrue-js 2.8.0 → 2.10.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 +44 -21
- package/dist/main/GoTrueClient.d.ts.map +1 -1
- package/dist/main/GoTrueClient.js +134 -77
- package/dist/main/GoTrueClient.js.map +1 -1
- package/dist/main/lib/helpers.d.ts +10 -0
- package/dist/main/lib/helpers.d.ts.map +1 -1
- package/dist/main/lib/helpers.js +40 -1
- package/dist/main/lib/helpers.js.map +1 -1
- package/dist/main/lib/types.d.ts +2 -0
- 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/GoTrueClient.d.ts +44 -21
- package/dist/module/GoTrueClient.d.ts.map +1 -1
- package/dist/module/GoTrueClient.js +136 -79
- package/dist/module/GoTrueClient.js.map +1 -1
- package/dist/module/lib/helpers.d.ts +10 -0
- package/dist/module/lib/helpers.d.ts.map +1 -1
- package/dist/module/lib/helpers.js +37 -0
- package/dist/module/lib/helpers.js.map +1 -1
- package/dist/module/lib/types.d.ts +2 -0
- 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 +1 -1
- package/src/GoTrueClient.ts +147 -74
- package/src/lib/helpers.ts +42 -0
- package/src/lib/types.ts +2 -0
- package/src/lib/version.ts +1 -1
package/src/GoTrueClient.ts
CHANGED
|
@@ -27,6 +27,8 @@ import {
|
|
|
27
27
|
resolveFetch,
|
|
28
28
|
setItemAsync,
|
|
29
29
|
uuid,
|
|
30
|
+
retryable,
|
|
31
|
+
sleep,
|
|
30
32
|
} from './lib/helpers'
|
|
31
33
|
import localStorageAdapter from './lib/local-storage'
|
|
32
34
|
import { polyfillGlobalThis } from './lib/polyfills'
|
|
@@ -79,6 +81,13 @@ const DEFAULT_OPTIONS: Omit<Required<GoTrueClientOptions>, 'fetch' | 'storage'>
|
|
|
79
81
|
headers: DEFAULT_HEADERS,
|
|
80
82
|
}
|
|
81
83
|
|
|
84
|
+
/** Current session will be checked for refresh at this interval. */
|
|
85
|
+
const AUTO_REFRESH_TICK_DURATION = 10 * 1000
|
|
86
|
+
|
|
87
|
+
/**
|
|
88
|
+
* A token refresh will be attempted this many ticks before the current session expires. */
|
|
89
|
+
const AUTO_REFRESH_TICK_THRESHOLD = 3
|
|
90
|
+
|
|
82
91
|
export default class GoTrueClient {
|
|
83
92
|
/**
|
|
84
93
|
* Namespace for the GoTrue admin methods.
|
|
@@ -104,8 +113,7 @@ export default class GoTrueClient {
|
|
|
104
113
|
protected persistSession: boolean
|
|
105
114
|
protected storage: SupportedStorage
|
|
106
115
|
protected stateChangeEmitters: Map<string, Subscription> = new Map()
|
|
107
|
-
protected
|
|
108
|
-
protected networkRetries = 0
|
|
116
|
+
protected autoRefreshTicker: ReturnType<typeof setInterval> | null = null
|
|
109
117
|
protected refreshingDeferred: Deferred<CallRefreshTokenResult> | null = null
|
|
110
118
|
/**
|
|
111
119
|
* Keeps track of the async client initialization.
|
|
@@ -142,7 +150,6 @@ export default class GoTrueClient {
|
|
|
142
150
|
this.fetch = resolveFetch(settings.fetch)
|
|
143
151
|
this.detectSessionInUrl = settings.detectSessionInUrl
|
|
144
152
|
|
|
145
|
-
this.initialize()
|
|
146
153
|
this.mfa = {
|
|
147
154
|
verify: this._verify.bind(this),
|
|
148
155
|
enroll: this._enroll.bind(this),
|
|
@@ -152,6 +159,8 @@ export default class GoTrueClient {
|
|
|
152
159
|
challengeAndVerify: this._challengeAndVerify.bind(this),
|
|
153
160
|
getAuthenticatorAssuranceLevel: this._getAuthenticatorAssuranceLevel.bind(this),
|
|
154
161
|
}
|
|
162
|
+
|
|
163
|
+
this.initialize()
|
|
155
164
|
}
|
|
156
165
|
|
|
157
166
|
/**
|
|
@@ -213,7 +222,7 @@ export default class GoTrueClient {
|
|
|
213
222
|
error: new AuthUnknownError('Unexpected error during initialization', error),
|
|
214
223
|
}
|
|
215
224
|
} finally {
|
|
216
|
-
this._handleVisibilityChange()
|
|
225
|
+
await this._handleVisibilityChange()
|
|
217
226
|
}
|
|
218
227
|
}
|
|
219
228
|
|
|
@@ -352,6 +361,7 @@ export default class GoTrueClient {
|
|
|
352
361
|
redirectTo: credentials.options?.redirectTo,
|
|
353
362
|
scopes: credentials.options?.scopes,
|
|
354
363
|
queryParams: credentials.options?.queryParams,
|
|
364
|
+
skipBrowserRedirect: credentials.options?.skipBrowserRedirect,
|
|
355
365
|
})
|
|
356
366
|
}
|
|
357
367
|
|
|
@@ -903,11 +913,26 @@ export default class GoTrueClient {
|
|
|
903
913
|
*/
|
|
904
914
|
private async _refreshAccessToken(refreshToken: string): Promise<AuthResponse> {
|
|
905
915
|
try {
|
|
906
|
-
|
|
907
|
-
|
|
908
|
-
|
|
909
|
-
|
|
910
|
-
|
|
916
|
+
const startedAt = Date.now()
|
|
917
|
+
|
|
918
|
+
// will attempt to refresh the token with exponential backoff
|
|
919
|
+
return await retryable(
|
|
920
|
+
async (attempt) => {
|
|
921
|
+
await sleep(attempt * 200) // 0, 200, 400, 800, ...
|
|
922
|
+
|
|
923
|
+
return await _request(this.fetch, 'POST', `${this.url}/token?grant_type=refresh_token`, {
|
|
924
|
+
body: { refresh_token: refreshToken },
|
|
925
|
+
headers: this.headers,
|
|
926
|
+
xform: _sessionResponse,
|
|
927
|
+
})
|
|
928
|
+
},
|
|
929
|
+
(attempt, _, result) =>
|
|
930
|
+
result &&
|
|
931
|
+
result.error &&
|
|
932
|
+
result.error instanceof AuthRetryableFetchError &&
|
|
933
|
+
// retryable only if the request can be sent before the backoff overflows the tick duration
|
|
934
|
+
Date.now() + (attempt + 1) * 200 - startedAt < AUTO_REFRESH_TICK_DURATION
|
|
935
|
+
)
|
|
911
936
|
} catch (error) {
|
|
912
937
|
if (isAuthError(error)) {
|
|
913
938
|
return { data: { session: null, user: null }, error }
|
|
@@ -933,6 +958,7 @@ export default class GoTrueClient {
|
|
|
933
958
|
redirectTo?: string
|
|
934
959
|
scopes?: string
|
|
935
960
|
queryParams?: { [key: string]: string }
|
|
961
|
+
skipBrowserRedirect?: boolean
|
|
936
962
|
} = {}
|
|
937
963
|
) {
|
|
938
964
|
const url: string = this._getUrlForProvider(provider, {
|
|
@@ -941,7 +967,7 @@ export default class GoTrueClient {
|
|
|
941
967
|
queryParams: options.queryParams,
|
|
942
968
|
})
|
|
943
969
|
// try to open on the browser
|
|
944
|
-
if (isBrowser()) {
|
|
970
|
+
if (isBrowser() && !options.skipBrowserRedirect) {
|
|
945
971
|
window.location.assign(url)
|
|
946
972
|
}
|
|
947
973
|
return { data: { provider, url }, error: null }
|
|
@@ -966,24 +992,12 @@ export default class GoTrueClient {
|
|
|
966
992
|
|
|
967
993
|
if ((currentSession.expires_at ?? Infinity) < timeNow + EXPIRY_MARGIN) {
|
|
968
994
|
if (this.autoRefreshToken && currentSession.refresh_token) {
|
|
969
|
-
this.networkRetries++
|
|
970
995
|
const { error } = await this._callRefreshToken(currentSession.refresh_token)
|
|
996
|
+
|
|
971
997
|
if (error) {
|
|
972
998
|
console.log(error.message)
|
|
973
|
-
if (
|
|
974
|
-
error instanceof AuthRetryableFetchError &&
|
|
975
|
-
this.networkRetries < NETWORK_FAILURE.MAX_RETRIES
|
|
976
|
-
) {
|
|
977
|
-
if (this.refreshTokenTimer) clearTimeout(this.refreshTokenTimer)
|
|
978
|
-
this.refreshTokenTimer = setTimeout(
|
|
979
|
-
() => this._recoverAndRefresh(),
|
|
980
|
-
NETWORK_FAILURE.RETRY_INTERVAL ** this.networkRetries * 100 // exponential backoff
|
|
981
|
-
)
|
|
982
|
-
return
|
|
983
|
-
}
|
|
984
999
|
await this._removeSession()
|
|
985
1000
|
}
|
|
986
|
-
this.networkRetries = 0
|
|
987
1001
|
} else {
|
|
988
1002
|
await this._removeSession()
|
|
989
1003
|
}
|
|
@@ -1052,14 +1066,6 @@ export default class GoTrueClient {
|
|
|
1052
1066
|
this.inMemorySession = session
|
|
1053
1067
|
}
|
|
1054
1068
|
|
|
1055
|
-
const expiresAt = session.expires_at
|
|
1056
|
-
if (expiresAt) {
|
|
1057
|
-
const timeNow = Math.round(Date.now() / 1000)
|
|
1058
|
-
const expiresIn = expiresAt - timeNow
|
|
1059
|
-
const refreshDurationBeforeExpires = expiresIn > EXPIRY_MARGIN ? EXPIRY_MARGIN : 0.5
|
|
1060
|
-
this._startAutoRefreshToken((expiresIn - refreshDurationBeforeExpires) * 1000)
|
|
1061
|
-
}
|
|
1062
|
-
|
|
1063
1069
|
if (this.persistSession && session.expires_at) {
|
|
1064
1070
|
await this._persistSession(session)
|
|
1065
1071
|
}
|
|
@@ -1075,57 +1081,133 @@ export default class GoTrueClient {
|
|
|
1075
1081
|
} else {
|
|
1076
1082
|
this.inMemorySession = null
|
|
1077
1083
|
}
|
|
1084
|
+
}
|
|
1085
|
+
|
|
1086
|
+
/**
|
|
1087
|
+
* Starts an auto-refresh process in the background. The session is checked
|
|
1088
|
+
* every few seconds. Close to the time of expiration a process is started to
|
|
1089
|
+
* refresh the session. If refreshing fails it will be retried for as long as
|
|
1090
|
+
* necessary.
|
|
1091
|
+
*
|
|
1092
|
+
* If you set the {@link GoTrueClientOptions#autoRefreshToken} you don't need
|
|
1093
|
+
* to call this function, it will be called for you.
|
|
1094
|
+
*
|
|
1095
|
+
* On browsers the refresh process works only when the tab/window is in the
|
|
1096
|
+
* foreground to conserve resources as well as prevent race conditions and
|
|
1097
|
+
* flooding auth with requests.
|
|
1098
|
+
*
|
|
1099
|
+
* On non-browser platforms the refresh process works *continuously* in the
|
|
1100
|
+
* background, which may not be desireable. You should hook into your
|
|
1101
|
+
* platform's foreground indication mechanism and call these methods
|
|
1102
|
+
* appropriately to conserve resources.
|
|
1103
|
+
*
|
|
1104
|
+
* {@see #stopAutoRefresh}
|
|
1105
|
+
*/
|
|
1106
|
+
async startAutoRefresh() {
|
|
1107
|
+
await this.stopAutoRefresh()
|
|
1108
|
+
this.autoRefreshTicker = setInterval(
|
|
1109
|
+
() => this._autoRefreshTokenTick(),
|
|
1110
|
+
AUTO_REFRESH_TICK_DURATION
|
|
1111
|
+
)
|
|
1112
|
+
|
|
1113
|
+
// run the tick immediately
|
|
1114
|
+
await this._autoRefreshTokenTick()
|
|
1115
|
+
}
|
|
1116
|
+
|
|
1117
|
+
/**
|
|
1118
|
+
* Stops an active auto refresh process running in the background (if any).
|
|
1119
|
+
* See {@link #startAutoRefresh} for more details.
|
|
1120
|
+
*/
|
|
1121
|
+
async stopAutoRefresh() {
|
|
1122
|
+
const ticker = this.autoRefreshTicker
|
|
1123
|
+
this.autoRefreshTicker = null
|
|
1078
1124
|
|
|
1079
|
-
if (
|
|
1080
|
-
|
|
1125
|
+
if (ticker) {
|
|
1126
|
+
clearInterval(ticker)
|
|
1081
1127
|
}
|
|
1082
1128
|
}
|
|
1083
1129
|
|
|
1084
1130
|
/**
|
|
1085
|
-
*
|
|
1086
|
-
* @param value time intervals in milliseconds.
|
|
1087
|
-
* @param session The current session.
|
|
1131
|
+
* Runs the auto refresh token tick.
|
|
1088
1132
|
*/
|
|
1089
|
-
private
|
|
1090
|
-
|
|
1091
|
-
if (value <= 0 || !this.autoRefreshToken) return
|
|
1133
|
+
private async _autoRefreshTokenTick() {
|
|
1134
|
+
const now = Date.now()
|
|
1092
1135
|
|
|
1093
|
-
|
|
1094
|
-
this.networkRetries++
|
|
1136
|
+
try {
|
|
1095
1137
|
const {
|
|
1096
1138
|
data: { session },
|
|
1097
|
-
error
|
|
1139
|
+
error,
|
|
1098
1140
|
} = await this.getSession()
|
|
1099
|
-
|
|
1100
|
-
|
|
1101
|
-
|
|
1102
|
-
|
|
1103
|
-
|
|
1104
|
-
|
|
1105
|
-
|
|
1106
|
-
|
|
1141
|
+
|
|
1142
|
+
if (!session || !session.refresh_token || !session.expires_at) {
|
|
1143
|
+
return
|
|
1144
|
+
}
|
|
1145
|
+
|
|
1146
|
+
// session will expire in this many ticks (or has already expired if <= 0)
|
|
1147
|
+
const expiresInTicks = Math.floor(
|
|
1148
|
+
(session.expires_at * 1000 - now) / AUTO_REFRESH_TICK_DURATION
|
|
1149
|
+
)
|
|
1150
|
+
|
|
1151
|
+
if (expiresInTicks < AUTO_REFRESH_TICK_THRESHOLD) {
|
|
1152
|
+
await this._callRefreshToken(session.refresh_token)
|
|
1107
1153
|
}
|
|
1108
|
-
}
|
|
1109
|
-
|
|
1154
|
+
} catch (e: any) {
|
|
1155
|
+
console.error('Auto refresh tick failed with error. This is likely a transient error.', e)
|
|
1156
|
+
}
|
|
1110
1157
|
}
|
|
1111
1158
|
|
|
1112
|
-
|
|
1159
|
+
/**
|
|
1160
|
+
* Registers callbacks on the browser / platform, which in-turn run
|
|
1161
|
+
* algorithms when the browser window/tab are in foreground. On non-browser
|
|
1162
|
+
* platforms it assumes always foreground.
|
|
1163
|
+
*/
|
|
1164
|
+
private async _handleVisibilityChange() {
|
|
1113
1165
|
if (!isBrowser() || !window?.addEventListener) {
|
|
1166
|
+
if (this.autoRefreshToken) {
|
|
1167
|
+
// in non-browser environments the refresh token ticker runs always
|
|
1168
|
+
this.startAutoRefresh()
|
|
1169
|
+
}
|
|
1170
|
+
|
|
1114
1171
|
return false
|
|
1115
1172
|
}
|
|
1116
1173
|
|
|
1117
1174
|
try {
|
|
1118
|
-
window?.addEventListener(
|
|
1119
|
-
|
|
1120
|
-
|
|
1121
|
-
|
|
1122
|
-
|
|
1123
|
-
|
|
1175
|
+
window?.addEventListener(
|
|
1176
|
+
'visibilitychange',
|
|
1177
|
+
async () => await this._onVisibilityChanged(false)
|
|
1178
|
+
)
|
|
1179
|
+
|
|
1180
|
+
// now immediately call the visbility changed callback to setup with the
|
|
1181
|
+
// current visbility state
|
|
1182
|
+
await this._onVisibilityChanged(true) // initial call
|
|
1124
1183
|
} catch (error) {
|
|
1125
1184
|
console.error('_handleVisibilityChange', error)
|
|
1126
1185
|
}
|
|
1127
1186
|
}
|
|
1128
1187
|
|
|
1188
|
+
/**
|
|
1189
|
+
* Callback registered with `window.addEventListener('visibilitychange')`.
|
|
1190
|
+
*/
|
|
1191
|
+
private async _onVisibilityChanged(isInitial: boolean) {
|
|
1192
|
+
if (document.visibilityState === 'visible') {
|
|
1193
|
+
if (!isInitial) {
|
|
1194
|
+
// initial visibility change setup is handled in another flow under #initialize()
|
|
1195
|
+
await this.initializePromise
|
|
1196
|
+
await this._recoverAndRefresh()
|
|
1197
|
+
}
|
|
1198
|
+
|
|
1199
|
+
if (this.autoRefreshToken) {
|
|
1200
|
+
// in browser environments the refresh token ticker runs only on focused tabs
|
|
1201
|
+
// which prevents race conditions
|
|
1202
|
+
this.startAutoRefresh()
|
|
1203
|
+
}
|
|
1204
|
+
} else if (document.visibilityState === 'hidden') {
|
|
1205
|
+
if (this.autoRefreshToken) {
|
|
1206
|
+
this.stopAutoRefresh()
|
|
1207
|
+
}
|
|
1208
|
+
}
|
|
1209
|
+
}
|
|
1210
|
+
|
|
1129
1211
|
/**
|
|
1130
1212
|
* Generates the relevant login URL for a third-party provider.
|
|
1131
1213
|
* @param options.redirectTo A URL or mobile address to send the user to after they are confirmed.
|
|
@@ -1174,10 +1256,7 @@ export default class GoTrueClient {
|
|
|
1174
1256
|
}
|
|
1175
1257
|
|
|
1176
1258
|
/**
|
|
1177
|
-
*
|
|
1178
|
-
* @param friendlyName Human readable name assigned to a device
|
|
1179
|
-
* @param factorType device which we're validating against. Can only be TOTP for now.
|
|
1180
|
-
* @param issuer domain which the user is enrolling with
|
|
1259
|
+
* {@see GoTrueMFAApi#enroll}
|
|
1181
1260
|
*/
|
|
1182
1261
|
private async _enroll(params: MFAEnrollParams): Promise<AuthMFAEnrollResponse> {
|
|
1183
1262
|
try {
|
|
@@ -1214,9 +1293,7 @@ export default class GoTrueClient {
|
|
|
1214
1293
|
}
|
|
1215
1294
|
|
|
1216
1295
|
/**
|
|
1217
|
-
*
|
|
1218
|
-
* @param factorId System assigned identifier for authenticator device as returned by enroll
|
|
1219
|
-
* @param code Code Generated by an authenticator device
|
|
1296
|
+
* {@see GoTrueMFAApi#verify}
|
|
1220
1297
|
*/
|
|
1221
1298
|
private async _verify(params: MFAVerifyParams): Promise<AuthMFAVerifyResponse> {
|
|
1222
1299
|
try {
|
|
@@ -1255,8 +1332,7 @@ export default class GoTrueClient {
|
|
|
1255
1332
|
}
|
|
1256
1333
|
|
|
1257
1334
|
/**
|
|
1258
|
-
*
|
|
1259
|
-
* @param factorId System assigned identifier for authenticator device as returned by enroll
|
|
1335
|
+
* {@see GoTrueMFAApi#challenge}
|
|
1260
1336
|
*/
|
|
1261
1337
|
private async _challenge(params: MFAChallengeParams): Promise<AuthMFAChallengeResponse> {
|
|
1262
1338
|
try {
|
|
@@ -1283,9 +1359,7 @@ export default class GoTrueClient {
|
|
|
1283
1359
|
}
|
|
1284
1360
|
|
|
1285
1361
|
/**
|
|
1286
|
-
*
|
|
1287
|
-
* @param factorId System assigned identifier for authenticator device as returned by enroll
|
|
1288
|
-
* @param code Code Generated by an authenticator device
|
|
1362
|
+
* {@see GoTrueMFAApi#challengeAndVerify}
|
|
1289
1363
|
*/
|
|
1290
1364
|
private async _challengeAndVerify(
|
|
1291
1365
|
params: MFAChallengeAndVerifyParams
|
|
@@ -1304,7 +1378,7 @@ export default class GoTrueClient {
|
|
|
1304
1378
|
}
|
|
1305
1379
|
|
|
1306
1380
|
/**
|
|
1307
|
-
*
|
|
1381
|
+
* {@see GoTrueMFAApi#listFactors}
|
|
1308
1382
|
*/
|
|
1309
1383
|
private async _listFactors(): Promise<AuthMFAListFactorsResponse> {
|
|
1310
1384
|
const {
|
|
@@ -1330,8 +1404,7 @@ export default class GoTrueClient {
|
|
|
1330
1404
|
}
|
|
1331
1405
|
|
|
1332
1406
|
/**
|
|
1333
|
-
*
|
|
1334
|
-
* and the current authentication methods for the session (AMR)
|
|
1407
|
+
* {@see GoTrueMFAApi#getAuthenticatorAssuranceLevel}
|
|
1335
1408
|
*/
|
|
1336
1409
|
private async _getAuthenticatorAssuranceLevel(): Promise<AuthMFAGetAuthenticatorAssuranceLevelResponse> {
|
|
1337
1410
|
const {
|
package/src/lib/helpers.ts
CHANGED
|
@@ -149,3 +149,45 @@ export function decodeJWTPayload(token: string) {
|
|
|
149
149
|
const base64Url = parts[1]
|
|
150
150
|
return JSON.parse(decodeBase64URL(base64Url))
|
|
151
151
|
}
|
|
152
|
+
|
|
153
|
+
/**
|
|
154
|
+
* Creates a promise that resolves to null after some time.
|
|
155
|
+
*/
|
|
156
|
+
export function sleep(time: number): Promise<null> {
|
|
157
|
+
return new Promise((accept) => {
|
|
158
|
+
setTimeout(() => accept(null), time)
|
|
159
|
+
})
|
|
160
|
+
}
|
|
161
|
+
|
|
162
|
+
/**
|
|
163
|
+
* Converts the provided async function into a retryable function. Each result
|
|
164
|
+
* or thrown error is sent to the isRetryable function which should return true
|
|
165
|
+
* if the function should run again.
|
|
166
|
+
*/
|
|
167
|
+
export function retryable<T>(
|
|
168
|
+
fn: (attempt: number) => Promise<T>,
|
|
169
|
+
isRetryable: (attempt: number, error: any | null, result?: T) => boolean
|
|
170
|
+
): Promise<T> {
|
|
171
|
+
const promise = new Promise<T>((accept, reject) => {
|
|
172
|
+
// eslint-disable-next-line @typescript-eslint/no-extra-semi
|
|
173
|
+
;(async () => {
|
|
174
|
+
for (let attempt = 0; attempt < Infinity; attempt++) {
|
|
175
|
+
try {
|
|
176
|
+
const result = await fn(attempt)
|
|
177
|
+
|
|
178
|
+
if (!isRetryable(attempt, null, result)) {
|
|
179
|
+
accept(result)
|
|
180
|
+
return
|
|
181
|
+
}
|
|
182
|
+
} catch (e: any) {
|
|
183
|
+
if (!isRetryable(attempt, e)) {
|
|
184
|
+
reject(e)
|
|
185
|
+
return
|
|
186
|
+
}
|
|
187
|
+
}
|
|
188
|
+
}
|
|
189
|
+
})()
|
|
190
|
+
})
|
|
191
|
+
|
|
192
|
+
return promise
|
|
193
|
+
}
|
package/src/lib/types.ts
CHANGED
|
@@ -440,6 +440,8 @@ export type SignInWithOAuthCredentials = {
|
|
|
440
440
|
scopes?: string
|
|
441
441
|
/** An object of query params */
|
|
442
442
|
queryParams?: { [key: string]: string }
|
|
443
|
+
/** If set to true does not immediately redirect the current browser context to visit the OAuth authorization page for the provider. */
|
|
444
|
+
skipBrowserRedirect?: boolean
|
|
443
445
|
}
|
|
444
446
|
}
|
|
445
447
|
|
package/src/lib/version.ts
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
1
|
// Generated by genversion.
|
|
2
|
-
export const version = '2.
|
|
2
|
+
export const version = '2.10.0'
|