@yboard/auth-mobile 0.0.1

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.
Files changed (37) hide show
  1. package/dist/index.d.mts +162 -0
  2. package/dist/index.d.ts +162 -0
  3. package/dist/index.js +2 -0
  4. package/dist/index.js.map +1 -0
  5. package/dist/index.mjs +2 -0
  6. package/dist/index.mjs.map +1 -0
  7. package/package.json +43 -0
  8. package/src/client/cookie-http-client.ts +137 -0
  9. package/src/client/cookie.ts +82 -0
  10. package/src/client/create-client.ts +311 -0
  11. package/src/client/errors.ts +6 -0
  12. package/src/client/exceptions/index.ts +1 -0
  13. package/src/client/exceptions/no-client-id-provided.exception.ts +11 -0
  14. package/src/client/globalFetch.ts +35 -0
  15. package/src/client/http-client.ts +209 -0
  16. package/src/client/index.ts +6 -0
  17. package/src/client/interfaces/authentication-response.interface.ts +34 -0
  18. package/src/client/interfaces/create-client-options.interface.ts +69 -0
  19. package/src/client/interfaces/get-authorization-url-options.interface.ts +15 -0
  20. package/src/client/interfaces/impersonator.interface.ts +9 -0
  21. package/src/client/interfaces/index.ts +9 -0
  22. package/src/client/interfaces/user.interface.ts +27 -0
  23. package/src/client/serializers/authentication-response.serializer.ts +27 -0
  24. package/src/client/serializers/index.ts +2 -0
  25. package/src/client/serializers/user.serializer.ts +15 -0
  26. package/src/client/utils/index.ts +5 -0
  27. package/src/client/utils/is-redirect-callback.ts +28 -0
  28. package/src/client/utils/memory-storage.ts +30 -0
  29. package/src/client/utils/native-storage.ts +43 -0
  30. package/src/client/utils/pkce.ts +36 -0
  31. package/src/client/utils/session-data.ts +59 -0
  32. package/src/client/utils/storage-keys.ts +7 -0
  33. package/src/index.ts +11 -0
  34. package/src/provider/authProvider.tsx +91 -0
  35. package/src/provider/context.ts +12 -0
  36. package/src/provider/hook.ts +13 -0
  37. package/src/provider/state.ts +17 -0
@@ -0,0 +1,311 @@
1
+ import * as AuthSession from "expo-auth-session";
2
+ import * as SecureStore from "expo-secure-store";
3
+ import * as WebBrowser from "expo-web-browser";
4
+ import { Platform } from "react-native";
5
+ import { getCookie, getSetCookie } from "./cookie";
6
+ import { CookieHttpClient } from "./cookie-http-client";
7
+ import { NoClientIdProvidedException } from "./exceptions";
8
+ import { NoOrganizationIdProvidedException } from "./exceptions/no-client-id-provided.exception";
9
+ import { HttpClient } from "./http-client";
10
+ import type { CreateClientOptions, User } from "./interfaces";
11
+ import {
12
+ createPkceChallenge,
13
+ isRedirectCallback,
14
+ memoryStorage,
15
+ storageKeys,
16
+ } from "./utils";
17
+
18
+ export interface RedirectOptions {
19
+ provider?: string;
20
+ context?: string;
21
+ invitationToken?: string;
22
+ loginHint?: string;
23
+ organizationId?: string;
24
+ passwordResetToken?: string;
25
+ state?: any;
26
+ type: "sign-in" | "sign-up";
27
+ }
28
+
29
+ export class Client {
30
+ readonly #httpClient: HttpClient | CookieHttpClient;
31
+ #redirectUri: string;
32
+
33
+ constructor(
34
+ clientId: string,
35
+ {
36
+ apiHostname: hostname,
37
+ https,
38
+ port,
39
+ organizationId,
40
+ redirectUri,
41
+ devMode,
42
+ }: CreateClientOptions,
43
+ ) {
44
+ if (!clientId) {
45
+ throw new NoClientIdProvidedException();
46
+ }
47
+ if (!organizationId) {
48
+ throw new NoOrganizationIdProvidedException();
49
+ }
50
+
51
+ // Platform-specific defaults
52
+ if (Platform.OS === "web") {
53
+ // --- Web defaults ---
54
+ redirectUri = redirectUri ?? window.origin;
55
+ devMode =
56
+ devMode ??
57
+ (location.hostname === "localhost" ||
58
+ location.hostname === "127.0.0.1");
59
+ } else {
60
+ // --- Native defaults ---
61
+ redirectUri = redirectUri ?? "";
62
+ devMode = devMode ?? false;
63
+ }
64
+
65
+ // Use CookieHttpClient for web (cookie-based), HttpClient for native (token-based)
66
+ if (Platform.OS === "web") {
67
+ this.#httpClient = new CookieHttpClient({
68
+ clientId,
69
+ hostname,
70
+ port,
71
+ organizationId,
72
+ https,
73
+ });
74
+ } else {
75
+ this.#httpClient = new HttpClient({
76
+ clientId,
77
+ hostname,
78
+ port,
79
+ organizationId,
80
+ https,
81
+ });
82
+ }
83
+
84
+ this.#redirectUri = redirectUri;
85
+ }
86
+
87
+ // ============================================================
88
+ // Cross-platform methods
89
+ // ============================================================
90
+
91
+ async getAccessToken(): Promise<string | null> {
92
+ if (Platform.OS === "web") {
93
+ return this.#getAccessTokenWeb();
94
+ } else {
95
+ return this.#getAccessTokenNative();
96
+ }
97
+ }
98
+
99
+ async getUser(): Promise<User | null> {
100
+ if (Platform.OS === "web") {
101
+ return this.#getUserWeb();
102
+ } else {
103
+ return this.#getUserNative();
104
+ }
105
+ }
106
+
107
+ async #redirect(options: RedirectOptions) {
108
+ if (Platform.OS === "web") {
109
+ return this.#redirectWeb(options);
110
+ } else {
111
+ return this.#redirectNative(options);
112
+ }
113
+ }
114
+
115
+ async initialize() {
116
+ const searchParams = new URLSearchParams(window.location.search);
117
+ if (isRedirectCallback(this.#redirectUri, searchParams)) {
118
+ await this.#handleCallback();
119
+ }
120
+ }
121
+
122
+ async signIn(opts: Omit<RedirectOptions, "type"> = {}) {
123
+ return this.#redirect({ ...opts, type: "sign-in" });
124
+ }
125
+
126
+ async signUp(opts: Omit<RedirectOptions, "type"> = {}) {
127
+ return this.#redirect({ ...opts, type: "sign-up" });
128
+ }
129
+
130
+ async signOut(options?: { returnTo: string }) {
131
+ if (Platform.OS === "web") {
132
+ return this.#signOutWeb(options);
133
+ } else {
134
+ return this.#signOutNative(options);
135
+ }
136
+ }
137
+
138
+ // Native methods
139
+ async #signOutNative(options?: { returnTo: string }) {
140
+ const redirectUri =
141
+ options?.returnTo ||
142
+ AuthSession.makeRedirectUri({ native: "yboardstarter:" });
143
+
144
+ const logoutUrl = await (this.#httpClient as HttpClient).getLogoutUrl({
145
+ returnTo: redirectUri,
146
+ });
147
+
148
+ if (logoutUrl) {
149
+ try {
150
+ const result = await WebBrowser.openAuthSessionAsync(
151
+ logoutUrl,
152
+ redirectUri,
153
+ );
154
+
155
+ if (result.type === "success") {
156
+ await SecureStore.deleteItemAsync("yboard-session");
157
+ } else {
158
+ console.warn("User cancelled or dismissed logout:", result.type);
159
+ }
160
+ } catch (error) {
161
+ console.error("Error during sign out:", error);
162
+ }
163
+ }
164
+ }
165
+
166
+ async #getAccessTokenNative(): Promise<string | null> {
167
+ const stored = await SecureStore.getItemAsync("yboard-session");
168
+ const cookie = getCookie(stored || "{}");
169
+ const accessToken = await (this.#httpClient as HttpClient).getAccessToken({
170
+ cookie,
171
+ });
172
+ return (accessToken as string) || null;
173
+ }
174
+
175
+ async #getUserNative(): Promise<User | null> {
176
+ const stored = await SecureStore.getItemAsync("yboard-session");
177
+ const cookie = getCookie(stored || "{}");
178
+ const user = await (this.#httpClient as HttpClient).getUser({ cookie });
179
+ if (!user) {
180
+ return null;
181
+ }
182
+ return user as User;
183
+ }
184
+
185
+ async #redirectNative({
186
+ context,
187
+ invitationToken,
188
+ loginHint,
189
+ organizationId,
190
+ passwordResetToken,
191
+ state,
192
+ }: RedirectOptions) {
193
+ const { codeVerifier, codeChallenge } = await createPkceChallenge();
194
+ memoryStorage.setItem(storageKeys.codeVerifier, codeVerifier);
195
+
196
+ const { code } = await (
197
+ this.#httpClient as HttpClient
198
+ ).startAuthorizationFlow({
199
+ codeChallenge,
200
+ codeChallengeMethod: "S256",
201
+ });
202
+
203
+ if (code) {
204
+ const cookie = await this.#authenticate({
205
+ code,
206
+ codeVerifier,
207
+ });
208
+ if (cookie && typeof cookie === "string") {
209
+ const prev = await SecureStore.getItemAsync("yboard-session");
210
+ const updated = getSetCookie(cookie, prev || undefined);
211
+ await SecureStore.setItemAsync("yboard-session", updated);
212
+ }
213
+ }
214
+ }
215
+
216
+ async #authenticate({
217
+ code,
218
+ codeVerifier,
219
+ }: {
220
+ code: string;
221
+ codeVerifier: string;
222
+ }): Promise<string | null> {
223
+ if (typeof codeVerifier !== "string") return null;
224
+
225
+ const cookie = await (this.#httpClient as HttpClient).authenticateWithCode({
226
+ code,
227
+ codeVerifier: codeVerifier,
228
+ redirectUri: this.#redirectUri,
229
+ });
230
+
231
+ return cookie;
232
+ }
233
+
234
+ // Web methods
235
+ async getCookieDomain(origin: string) {
236
+ const url = new URL(origin);
237
+ const domainParts = url.hostname.split(".");
238
+ if (domainParts.length > 1) {
239
+ return "." + domainParts.slice(-2).join(".");
240
+ }
241
+ return url.hostname;
242
+ }
243
+
244
+ async #signOutWeb(options?: { returnTo: string }) {
245
+ const url = await (this.#httpClient as CookieHttpClient).getLogoutUrl({
246
+ returnTo: options?.returnTo,
247
+ });
248
+
249
+ if (url) {
250
+ const domain = await this.getCookieDomain(this.#redirectUri);
251
+ document.cookie = `yboard-session=; expires=Thu, 01 Jan 1970 00:00:00 UTC; path=/; domain=${domain}`;
252
+ window.location.assign(url);
253
+ }
254
+ }
255
+
256
+ async #getAccessTokenWeb(): Promise<string | null> {
257
+ const accessToken = await (
258
+ this.#httpClient as CookieHttpClient
259
+ ).getAccessToken();
260
+ return accessToken as string | null;
261
+ }
262
+
263
+ async #getUserWeb(): Promise<User | null> {
264
+ const user = await (this.#httpClient as CookieHttpClient).getUser();
265
+ return user as User | null;
266
+ }
267
+
268
+ async #handleCallback() {
269
+ const cleanUrl = new URL(window.location.toString());
270
+ cleanUrl.search = "";
271
+ window.history.replaceState({}, "", cleanUrl);
272
+ }
273
+
274
+ async #redirectWeb({
275
+ context,
276
+ invitationToken,
277
+ loginHint,
278
+ organizationId,
279
+ passwordResetToken,
280
+ state,
281
+ type,
282
+ provider,
283
+ }: RedirectOptions) {
284
+ const url = await (
285
+ this.#httpClient as CookieHttpClient
286
+ ).getAuthorizationUrl({
287
+ context,
288
+ invitationToken,
289
+ loginHint,
290
+ organizationId,
291
+ passwordResetToken,
292
+ redirectUri: this.#redirectUri,
293
+ state: state ? JSON.stringify(state) : undefined,
294
+ });
295
+ window.location.assign(url);
296
+ }
297
+ }
298
+
299
+ export async function createClient(
300
+ clientId: string,
301
+ options: CreateClientOptions,
302
+ ) {
303
+ const client = new Client(clientId, options);
304
+
305
+ // Only initialize for web platform
306
+ if (Platform.OS === "web") {
307
+ await client.initialize();
308
+ }
309
+
310
+ return client;
311
+ }
@@ -0,0 +1,6 @@
1
+ export class AuthKitError extends Error {}
2
+ export class RefreshError extends AuthKitError {}
3
+ export class CodeExchangeError extends AuthKitError {}
4
+ export class LoginRequiredError extends AuthKitError {
5
+ readonly message: string = "No access token available";
6
+ }
@@ -0,0 +1 @@
1
+ export { NoClientIdProvidedException } from "./no-client-id-provided.exception";
@@ -0,0 +1,11 @@
1
+ export class NoClientIdProvidedException extends Error {
2
+ readonly status: number = 500;
3
+ readonly name: string = "NoClientIdProvidedException";
4
+ readonly message: string = `Missing Client ID. Pass it to the constructor (createClient("client_01HXRMBQ9BJ3E7QSTQ9X2PHVB7"))`;
5
+ }
6
+
7
+ export class NoOrganizationIdProvidedException extends Error {
8
+ readonly status: number = 500;
9
+ readonly name: string = "NoOrganizationIdProvidedException";
10
+ readonly message: string = `Missing Organization ID. Pass it to the constructor`;
11
+ }
@@ -0,0 +1,35 @@
1
+ export const fetchWithOrganizationIdAndCookie = ({
2
+ baseUrl,
3
+ organizationId,
4
+ cookie,
5
+ path,
6
+ method,
7
+ options,
8
+ body = {},
9
+ }: {
10
+ baseUrl: string;
11
+ organizationId: string;
12
+ cookie?: string;
13
+ path: string;
14
+ method: "GET" | "POST" | "PUT" | "DELETE";
15
+ options?: RequestInit;
16
+ body?: Record<string, unknown>;
17
+ }) => {
18
+ const fetchOptions: RequestInit = {
19
+ method,
20
+ headers: {
21
+ "Accept": "application/json, text/plain, */*",
22
+ "Content-Type": "application/json",
23
+ "X-Organization-Id": organizationId,
24
+ "cookie": cookie || "",
25
+ },
26
+ credentials: "include",
27
+ ...options,
28
+ };
29
+
30
+ if (method !== "GET" && body) {
31
+ fetchOptions.body = JSON.stringify(body);
32
+ }
33
+
34
+ return fetch(`${baseUrl}${path}`, fetchOptions);
35
+ };
@@ -0,0 +1,209 @@
1
+ import * as AuthSession from "expo-auth-session";
2
+ import * as WebBrowser from "expo-web-browser";
3
+ import { CodeExchangeError } from "./errors";
4
+ import { fetchWithOrganizationIdAndCookie } from "./globalFetch";
5
+ import { User } from "./interfaces";
6
+
7
+ export class HttpClient {
8
+ readonly #baseUrl: string;
9
+ readonly #clientId: string;
10
+ readonly #organizationId: string;
11
+
12
+ constructor({
13
+ clientId,
14
+ hostname,
15
+ port,
16
+ organizationId,
17
+ https = true,
18
+ }: {
19
+ clientId: string;
20
+ hostname?: string;
21
+ organizationId: string;
22
+ port?: number;
23
+ https?: boolean;
24
+ }) {
25
+ this.#baseUrl = `${https ? "https" : "http"}://${hostname}${port ? `:${port}` : ""}`;
26
+ this.#clientId = clientId;
27
+ this.#organizationId = organizationId;
28
+ }
29
+
30
+ #buildAuthUrl({
31
+ redirectUri,
32
+ codeChallenge,
33
+ codeChallengeMethod,
34
+ clientId,
35
+ organizationId,
36
+ }: {
37
+ redirectUri: string;
38
+ codeChallenge: string;
39
+ codeChallengeMethod: string;
40
+ clientId: string;
41
+ organizationId: string;
42
+ }) {
43
+ const params = new URLSearchParams({
44
+ response_type: "code",
45
+ clientId,
46
+ redirectUri,
47
+ codeChallenge,
48
+ codeChallengeMethod,
49
+ organizationId,
50
+ });
51
+
52
+ return `${this.#baseUrl}/api/user_management/mobile/signIn?${params.toString()}`;
53
+ }
54
+
55
+ async startAuthorizationFlow({
56
+ codeChallenge,
57
+ codeChallengeMethod,
58
+ }: {
59
+ codeChallenge: string;
60
+ codeChallengeMethod: "S256";
61
+ }) {
62
+ const redirectUri = AuthSession.makeRedirectUri({
63
+ native: "yboardstarter:",
64
+ }).toString();
65
+ const authUrl = this.#buildAuthUrl({
66
+ redirectUri,
67
+ codeChallenge,
68
+ codeChallengeMethod,
69
+ clientId: this.#clientId,
70
+ organizationId: this.#organizationId,
71
+ });
72
+
73
+ let code: string | undefined;
74
+
75
+ const webResult = await WebBrowser.openAuthSessionAsync(
76
+ authUrl,
77
+ redirectUri,
78
+ );
79
+
80
+ switch (webResult.type) {
81
+ case "success":
82
+ if (webResult.url) {
83
+ const urlParts = webResult.url.split("?");
84
+ if (urlParts.length > 1) {
85
+ const queryString = urlParts[1];
86
+ const params = queryString.split("&");
87
+ for (const param of params) {
88
+ const [key, value] = param.split("=");
89
+ if (key === "code") {
90
+ code = decodeURIComponent(value);
91
+ break;
92
+ }
93
+ }
94
+ }
95
+ } else {
96
+ console.warn("Success result but no URL returned");
97
+ }
98
+ break;
99
+
100
+ case "cancel":
101
+ console.warn("User cancelled the auth flow.");
102
+ throw new Error("Authentication cancelled.");
103
+
104
+ case "dismiss":
105
+ console.warn(
106
+ "Auth flow was dismissed (possibly due to backgrounding).",
107
+ );
108
+ throw new Error("Authentication dismissed.");
109
+
110
+ case "locked":
111
+ console.warn("Another auth session is already in progress.");
112
+ throw new Error("Authentication session already active.");
113
+
114
+ default:
115
+ console.error("Unhandled web result type:", webResult.type);
116
+ throw new Error(`Unhandled auth session result: ${webResult.type}`);
117
+ }
118
+
119
+ if (!code) {
120
+ throw new Error("No authorization code found in redirect URL.");
121
+ }
122
+
123
+ return { code };
124
+ }
125
+
126
+ async authenticateWithCode({
127
+ code,
128
+ codeVerifier,
129
+ redirectUri,
130
+ }: {
131
+ code: string;
132
+ codeVerifier: string;
133
+ redirectUri: string;
134
+ }): Promise<string | null> {
135
+ const response = await fetch(
136
+ `${this.#baseUrl}/api/user_management/mobile/authenticate`,
137
+ {
138
+ method: "POST",
139
+ headers: {
140
+ "Content-Type": "application/json",
141
+ "X-Organization-Id": this.#organizationId,
142
+ },
143
+ body: JSON.stringify({
144
+ code,
145
+ client_id: this.#clientId,
146
+ grant_type: "authorization_code",
147
+ code_verifier: codeVerifier,
148
+ redirect_uri: redirectUri,
149
+ }),
150
+ },
151
+ );
152
+
153
+ if (!response.ok) {
154
+ const error = await response.json();
155
+ throw new CodeExchangeError(error.error_description);
156
+ }
157
+
158
+ const setCookie = response.headers.get("set-cookie");
159
+ return setCookie;
160
+ }
161
+
162
+ async getUser({ cookie }: { cookie?: string } = {}) {
163
+ const response = await fetchWithOrganizationIdAndCookie({
164
+ baseUrl: this.#baseUrl,
165
+ organizationId: this.#organizationId,
166
+ cookie,
167
+ path: "/api/user_management/mobile/getUser",
168
+ method: "GET",
169
+ });
170
+
171
+ if (!response.ok) {
172
+ return null;
173
+ }
174
+ const { user } = (await response.json()) as { user: User };
175
+ return user;
176
+ }
177
+
178
+ async getAccessToken({ cookie }: { cookie?: string } = {}) {
179
+ const response = await fetchWithOrganizationIdAndCookie({
180
+ baseUrl: this.#baseUrl,
181
+ organizationId: this.#organizationId,
182
+ cookie,
183
+ path: "/api/user_management/mobile/getAccessToken",
184
+ method: "GET",
185
+ });
186
+
187
+ const { accessToken } = (await response.json()) as { accessToken: string };
188
+ return accessToken;
189
+ }
190
+
191
+ async getLogoutUrl({ returnTo }: { returnTo?: string } = {}): Promise<
192
+ string | null
193
+ > {
194
+ const response = await fetch(
195
+ `${this.#baseUrl}/api/user_management/mobile/getLogOutUrl`,
196
+ {
197
+ method: "POST",
198
+ headers: {
199
+ "Content-Type": "application/json",
200
+ "X-Organization-Id": this.#organizationId,
201
+ },
202
+ body: JSON.stringify({ client_id: this.#clientId, returnTo }),
203
+ },
204
+ );
205
+
206
+ const { url } = await response.json();
207
+ return url;
208
+ }
209
+ }
@@ -0,0 +1,6 @@
1
+ export { createClient } from "./create-client";
2
+ export type { RedirectOptions } from "./create-client";
3
+ export { getClaims } from "./utils/session-data";
4
+ export type { User, AuthenticationResponse } from "./interfaces";
5
+ export { AuthKitError, LoginRequiredError } from "./errors";
6
+ export { memoryStorage } from "./utils/memory-storage";
@@ -0,0 +1,34 @@
1
+ import type { User, UserRaw } from "./user.interface";
2
+ import type { Impersonator, ImpersonatorRaw } from "./impersonator.interface";
3
+
4
+ export interface AuthenticationResponse {
5
+ user: User;
6
+ accessToken: string;
7
+ refreshToken: string;
8
+ organizationId?: string;
9
+ impersonator?: Impersonator;
10
+ sealedSession?: string;
11
+ }
12
+
13
+ export interface AuthenticationResponseWithOrganizationSelection {
14
+ rawData: {
15
+ code: string;
16
+ message: string;
17
+ pending_authentication_token: string;
18
+ user: User;
19
+ organizations: { id: string; name: string }[];
20
+ requestId: string;
21
+ }
22
+ status: number;
23
+ }
24
+
25
+ export type OnRefreshResponse = Omit<AuthenticationResponse, "refreshToken">;
26
+
27
+ export interface AuthenticationResponseRaw {
28
+ user: UserRaw;
29
+ access_token: string;
30
+ refresh_token: string;
31
+ organization_id?: string;
32
+ impersonator?: ImpersonatorRaw;
33
+ sealedSession?: string;
34
+ }
@@ -0,0 +1,69 @@
1
+ import type {
2
+ AuthenticationResponse,
3
+ OnRefreshResponse,
4
+ } from "./authentication-response.interface";
5
+
6
+ export interface CreateClientOptions {
7
+ /**
8
+ * How many seconds before the access token expiration to attempt a refresh.
9
+ */
10
+ refreshBufferInterval?: number;
11
+
12
+ /**
13
+ * The API hostname to connect to
14
+ */
15
+ apiHostname?: string;
16
+
17
+ /**
18
+ * Whether to use HTTPS (default: true)
19
+ */
20
+ https?: boolean;
21
+
22
+ /**
23
+ * The port number to connect to
24
+ */
25
+ port?: number;
26
+
27
+ /**
28
+ * The organization ID for authentication
29
+ */
30
+ organizationId: string;
31
+
32
+ /**
33
+ * The redirect URI for OAuth flow
34
+ */
35
+ redirectUri?: string;
36
+
37
+ /**
38
+ * Whether the app is running in development mode
39
+ * For web: defaults to true if on localhost or 127.0.0.1
40
+ * For native: defaults to false
41
+ */
42
+ devMode?: boolean;
43
+
44
+ /**
45
+ * Callback to determine if auto-refresh should proceed
46
+ * For web: defaults to checking if document is not hidden
47
+ * For native: defaults to always true
48
+ */
49
+ onBeforeAutoRefresh?: () => boolean;
50
+
51
+ /**
52
+ * Callback invoked after successful redirect with authentication data
53
+ */
54
+ onRedirectCallback?: (params: RedirectParams) => void;
55
+
56
+ /**
57
+ * Callback invoked when a token refresh occurs
58
+ */
59
+ onRefresh?: (response: OnRefreshResponse) => void;
60
+
61
+ /**
62
+ * Callback invoked when token refresh fails
63
+ */
64
+ onRefreshFailure?: (params: { signIn: () => Promise<void> }) => void;
65
+ }
66
+
67
+ export interface RedirectParams extends AuthenticationResponse {
68
+ state: Record<string, any> | null;
69
+ }
@@ -0,0 +1,15 @@
1
+ export interface GetAuthorizationUrlOptions {
2
+ connectionId?: string;
3
+ context?: string;
4
+ organizationId?: string;
5
+ domainHint?: string;
6
+ loginHint?: string;
7
+ provider?: string;
8
+ redirectUri?: string;
9
+ state?: string;
10
+ screenHint?: "sign-up" | "sign-in";
11
+ invitationToken?: string;
12
+ passwordResetToken?: string;
13
+ codeChallenge?: string;
14
+ codeChallengeMethod?: string;
15
+ }