@base44-preview/sdk 0.8.52-pr.298.d08e0ba → 0.8.52-pr.301.707876a
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 +0 -2
- package/dist/index.d.ts +0 -1
- package/dist/modules/auth.js +6 -13
- package/dist/modules/auth.types.d.ts +3 -7
- package/package.json +4 -22
- package/dist/modules/mfa.d.ts +0 -52
- package/dist/modules/mfa.js +0 -43
package/README.md
CHANGED
package/dist/index.d.ts
CHANGED
|
@@ -18,4 +18,3 @@ export { Actor, type Conn } from "./actor.js";
|
|
|
18
18
|
export type { ConnectorsModule, UserConnectorsModule, ConnectorApiRequest, ConnectorApiResponse, ConnectorApiResponsePhase, } from "./modules/connectors.types.js";
|
|
19
19
|
export type { CustomIntegrationsModule, CustomIntegrationCallParams, CustomIntegrationCallResponse, } from "./modules/custom-integrations.types.js";
|
|
20
20
|
export type { GetAccessTokenOptions, SaveAccessTokenOptions, RemoveAccessTokenOptions, GetLoginUrlOptions, } from "./utils/auth-utils.types.js";
|
|
21
|
-
export type { MfaChallenge, MfaModule, MfaProof, LoginResult, MfaEnrollmentResult } from "./modules/mfa.js";
|
package/dist/modules/auth.js
CHANGED
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
import { createMfaModule, prepareMfaPkce } from "./mfa.js";
|
|
2
1
|
import { resetAnalyticsSessionContext } from "./analytics.js";
|
|
3
2
|
function isInsideIframe() {
|
|
4
3
|
if (typeof window === "undefined")
|
|
@@ -20,9 +19,9 @@ function loginViaPopup(url, redirectUrl, expectedOrigin) {
|
|
|
20
19
|
const height = 600;
|
|
21
20
|
const left = Math.round(window.screenX + (window.outerWidth - width) / 2);
|
|
22
21
|
const top = Math.round(window.screenY + (window.outerHeight - height) / 2);
|
|
23
|
-
const popup = window.open(
|
|
22
|
+
const popup = window.open(url, "base44_auth", `width=${width},height=${height},left=${left},top=${top},resizable=yes,scrollbars=yes`);
|
|
24
23
|
if (!popup) {
|
|
25
|
-
return
|
|
24
|
+
return;
|
|
26
25
|
}
|
|
27
26
|
const cleanup = () => {
|
|
28
27
|
window.removeEventListener("message", onMessage);
|
|
@@ -53,7 +52,6 @@ function loginViaPopup(url, redirectUrl, expectedOrigin) {
|
|
|
53
52
|
cleanup();
|
|
54
53
|
}, 500);
|
|
55
54
|
window.addEventListener("message", onMessage);
|
|
56
|
-
return url.then(value => { popup.location.href = value; }, error => { cleanup(); throw error; });
|
|
57
55
|
}
|
|
58
56
|
/**
|
|
59
57
|
* Creates the auth module for the Base44 SDK.
|
|
@@ -84,8 +82,7 @@ export function createAuthModule(axios, functionsAxiosClient, appId, options) {
|
|
|
84
82
|
// to the identity transitions below (`setToken`, `logout`) instead of to the
|
|
85
83
|
// header a caller may have set on the instance directly.
|
|
86
84
|
let hasAccessToken = Boolean(options.token);
|
|
87
|
-
|
|
88
|
-
mfa: createMfaModule(axios, appId, token => module.setToken(token)),
|
|
85
|
+
return {
|
|
89
86
|
hasToken() {
|
|
90
87
|
return hasAccessToken;
|
|
91
88
|
},
|
|
@@ -122,10 +119,9 @@ export function createAuthModule(axios, functionsAxiosClient, appId, options) {
|
|
|
122
119
|
window.location.href = loginUrl;
|
|
123
120
|
},
|
|
124
121
|
// Redirects the user to a provider's login page
|
|
125
|
-
|
|
122
|
+
loginWithProvider(provider, fromUrl = "/") {
|
|
126
123
|
// Build the full redirect URL
|
|
127
124
|
const redirectUrl = new URL(fromUrl, window.location.origin).toString();
|
|
128
|
-
const mfaPkce = provider === "sso" ? Promise.resolve("") : prepareMfaPkce(appId).then(value => `&app_mfa_code_challenge=${value}`);
|
|
129
125
|
const queryParams = `app_id=${appId}&from_url=${encodeURIComponent(redirectUrl)}`;
|
|
130
126
|
// SSO uses a different URL structure with appId in the path
|
|
131
127
|
let authPath;
|
|
@@ -141,11 +137,11 @@ export function createAuthModule(axios, functionsAxiosClient, appId, options) {
|
|
|
141
137
|
// When running inside an iframe, use a popup to avoid OAuth providers
|
|
142
138
|
// blocking iframe navigation.
|
|
143
139
|
if (isInsideIframe()) {
|
|
144
|
-
const popupLoginUrl =
|
|
140
|
+
const popupLoginUrl = `${loginUrl}&popup_origin=${encodeURIComponent(window.location.origin)}`;
|
|
145
141
|
return loginViaPopup(popupLoginUrl, redirectUrl, window.location.origin);
|
|
146
142
|
}
|
|
147
143
|
// Default: full-page redirect
|
|
148
|
-
window.location.href = loginUrl
|
|
144
|
+
window.location.href = loginUrl;
|
|
149
145
|
},
|
|
150
146
|
// Logout the current user
|
|
151
147
|
logout(redirectUrl) {
|
|
@@ -211,8 +207,6 @@ export function createAuthModule(axios, functionsAxiosClient, appId, options) {
|
|
|
211
207
|
password,
|
|
212
208
|
...(turnstileToken && { turnstile_token: turnstileToken }),
|
|
213
209
|
});
|
|
214
|
-
if (response.mfa_required)
|
|
215
|
-
return response;
|
|
216
210
|
const { access_token, user } = response;
|
|
217
211
|
if (access_token) {
|
|
218
212
|
this.setToken(access_token);
|
|
@@ -284,5 +278,4 @@ export function createAuthModule(axios, functionsAxiosClient, appId, options) {
|
|
|
284
278
|
});
|
|
285
279
|
},
|
|
286
280
|
};
|
|
287
|
-
return module;
|
|
288
281
|
}
|
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
import type { LoginResult, MfaModule } from "./mfa.js";
|
|
2
1
|
/**
|
|
3
2
|
* An authenticated user.
|
|
4
3
|
*/
|
|
@@ -38,7 +37,6 @@ export interface User {
|
|
|
38
37
|
* Response from login endpoints containing user information and access token.
|
|
39
38
|
*/
|
|
40
39
|
export interface LoginResponse {
|
|
41
|
-
mfa_required?: false;
|
|
42
40
|
/** JWT access token for authentication. */
|
|
43
41
|
access_token: string;
|
|
44
42
|
/** User information. */
|
|
@@ -119,8 +117,6 @@ export interface AuthModuleOptions {
|
|
|
119
117
|
* The auth module is only available in user authentication mode (`base44.auth`).
|
|
120
118
|
*/
|
|
121
119
|
export interface AuthModule {
|
|
122
|
-
/** Multi-factor enrollment and login for this app. */
|
|
123
|
-
mfa: MfaModule;
|
|
124
120
|
/**
|
|
125
121
|
* Gets the current authenticated user's information.
|
|
126
122
|
*
|
|
@@ -223,7 +219,7 @@ export interface AuthModule {
|
|
|
223
219
|
* ```
|
|
224
220
|
*
|
|
225
221
|
*/
|
|
226
|
-
loginWithProvider(provider: string, fromUrl?: string):
|
|
222
|
+
loginWithProvider(provider: string, fromUrl?: string): void;
|
|
227
223
|
/**
|
|
228
224
|
* Logs out the current user.
|
|
229
225
|
*
|
|
@@ -306,7 +302,7 @@ export interface AuthModule {
|
|
|
306
302
|
* );
|
|
307
303
|
* ```
|
|
308
304
|
*/
|
|
309
|
-
loginViaEmailPassword(email: string, password: string, turnstileToken?: string): Promise<
|
|
305
|
+
loginViaEmailPassword(email: string, password: string, turnstileToken?: string): Promise<LoginResponse>;
|
|
310
306
|
/**
|
|
311
307
|
* Checks if the current user is authenticated.
|
|
312
308
|
*
|
|
@@ -431,7 +427,7 @@ export interface AuthModule {
|
|
|
431
427
|
* );
|
|
432
428
|
* ```
|
|
433
429
|
*/
|
|
434
|
-
verifyOtp(params: VerifyOtpParams): Promise<
|
|
430
|
+
verifyOtp(params: VerifyOtpParams): Promise<any>;
|
|
435
431
|
/**
|
|
436
432
|
* Resends an OTP code to the user's email address.
|
|
437
433
|
*
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@base44-preview/sdk",
|
|
3
|
-
"version": "0.8.52-pr.
|
|
3
|
+
"version": "0.8.52-pr.301.707876a",
|
|
4
4
|
"description": "JavaScript SDK for Base44 API",
|
|
5
5
|
"main": "dist/index.js",
|
|
6
6
|
"types": "dist/index.d.ts",
|
|
@@ -10,7 +10,6 @@
|
|
|
10
10
|
],
|
|
11
11
|
"scripts": {
|
|
12
12
|
"build": "tsc",
|
|
13
|
-
"lint": "eslint src",
|
|
14
13
|
"test": "npm run test:types && vitest run",
|
|
15
14
|
"test:types": "tsc --noEmit -p tsconfig.type-tests.json",
|
|
16
15
|
"test:unit": "vitest run tests/unit",
|
|
@@ -31,24 +30,6 @@
|
|
|
31
30
|
"socket.io-client": "^4.8.3",
|
|
32
31
|
"uuid": "^13.0.2"
|
|
33
32
|
},
|
|
34
|
-
"devDependencies": {
|
|
35
|
-
"@types/hast": "^3.0.4",
|
|
36
|
-
"@types/node": "^25.0.1",
|
|
37
|
-
"@types/unist": "^3.0.3",
|
|
38
|
-
"@typescript-eslint/parser": "^8.51.0",
|
|
39
|
-
"@vitest/coverage-istanbul": "^4.1.9",
|
|
40
|
-
"@vitest/coverage-v8": "^4.1.9",
|
|
41
|
-
"@vitest/ui": "^4.1.9",
|
|
42
|
-
"dotenv": "^16.3.1",
|
|
43
|
-
"eslint": "^9.39.2",
|
|
44
|
-
"eslint-plugin-import": "^2.32.0",
|
|
45
|
-
"nock": "^13.4.0",
|
|
46
|
-
"typedoc": "^0.28.14",
|
|
47
|
-
"typedoc-plugin-markdown": "^4.9.0",
|
|
48
|
-
"typescript": "^5.3.2",
|
|
49
|
-
"typescript-eslint": "^8.51.0",
|
|
50
|
-
"vitest": "^4.1.9"
|
|
51
|
-
},
|
|
52
33
|
"keywords": [
|
|
53
34
|
"base44",
|
|
54
35
|
"api",
|
|
@@ -58,10 +39,11 @@
|
|
|
58
39
|
"license": "MIT",
|
|
59
40
|
"repository": {
|
|
60
41
|
"type": "git",
|
|
61
|
-
"url": "git+https://github.com/base44/javascript-sdk.git"
|
|
42
|
+
"url": "git+https://github.com/base44/javascript-sdk.git",
|
|
43
|
+
"directory": "packages/sdk"
|
|
62
44
|
},
|
|
63
45
|
"bugs": {
|
|
64
46
|
"url": "https://github.com/base44/javascript-sdk/issues"
|
|
65
47
|
},
|
|
66
|
-
"homepage": "https://github.com/base44/javascript-sdk#readme"
|
|
48
|
+
"homepage": "https://github.com/base44/javascript-sdk/tree/main/packages/sdk#readme"
|
|
67
49
|
}
|
package/dist/modules/mfa.d.ts
DELETED
|
@@ -1,52 +0,0 @@
|
|
|
1
|
-
import type { AxiosInstance } from 'axios';
|
|
2
|
-
import type { LoginResponse } from './auth.types.js';
|
|
3
|
-
/** A restricted, short-lived login outcome. It is never an access token. */
|
|
4
|
-
export interface MfaChallenge {
|
|
5
|
-
mfa_required: true;
|
|
6
|
-
next_step: 'enroll' | 'verify';
|
|
7
|
-
mfa_methods: ('totp' | 'sms')[];
|
|
8
|
-
mfa_session_token: string;
|
|
9
|
-
expires_in_seconds: number;
|
|
10
|
-
phone_hint?: string;
|
|
11
|
-
access_token?: never;
|
|
12
|
-
user?: never;
|
|
13
|
-
}
|
|
14
|
-
export type LoginResult = LoginResponse | MfaChallenge;
|
|
15
|
-
export interface MfaEnrollmentResult extends LoginResponse {
|
|
16
|
-
backup_codes?: string[];
|
|
17
|
-
}
|
|
18
|
-
export interface MfaProof {
|
|
19
|
-
code: string;
|
|
20
|
-
method: 'totp' | 'sms';
|
|
21
|
-
remember_device?: boolean;
|
|
22
|
-
}
|
|
23
|
-
/** App-scoped MFA. Pass the challenge credential explicitly; do not set it as the SDK token. */
|
|
24
|
-
export interface MfaModule {
|
|
25
|
-
getStatus(): Promise<{
|
|
26
|
-
mfa_enabled: boolean;
|
|
27
|
-
methods: ('totp' | 'sms')[];
|
|
28
|
-
backup_codes_remaining: number;
|
|
29
|
-
policy: 'off' | 'required';
|
|
30
|
-
}>;
|
|
31
|
-
/** Requires an app admin session; resets a user in this app only. */
|
|
32
|
-
resetForUser(appUserId: string): Promise<{
|
|
33
|
-
success: true;
|
|
34
|
-
}>;
|
|
35
|
-
/** Open managed settings with fresh primary authentication and factor verification. */
|
|
36
|
-
openSecurity(returnTo?: string): void;
|
|
37
|
-
setupTotp(challenge: MfaChallenge): Promise<{
|
|
38
|
-
secret: string;
|
|
39
|
-
secret_formatted: string;
|
|
40
|
-
qr_code: string;
|
|
41
|
-
}>;
|
|
42
|
-
sendSms(challenge: MfaChallenge, phoneNumber: string): Promise<unknown>;
|
|
43
|
-
enrollTotp(challenge: MfaChallenge, code: string, rememberDevice?: boolean): Promise<MfaEnrollmentResult>;
|
|
44
|
-
enrollSms(challenge: MfaChallenge, code: string, rememberDevice?: boolean): Promise<MfaEnrollmentResult>;
|
|
45
|
-
verify(challenge: MfaChallenge, proof: MfaProof): Promise<LoginResponse>;
|
|
46
|
-
verifyRecoveryCode(challenge: MfaChallenge, code: string, rememberDevice?: boolean): Promise<LoginResponse>;
|
|
47
|
-
resendSms(challenge: MfaChallenge): Promise<unknown>;
|
|
48
|
-
/** Open Base44's managed MFA flow on this app's origin. */
|
|
49
|
-
continueLogin(challenge: MfaChallenge, returnTo?: string): Promise<void>;
|
|
50
|
-
}
|
|
51
|
-
export declare function prepareMfaPkce(appId: string): Promise<string>;
|
|
52
|
-
export declare function createMfaModule(axios: AxiosInstance, appId: string, setToken: (token: string) => void): MfaModule;
|
package/dist/modules/mfa.js
DELETED
|
@@ -1,43 +0,0 @@
|
|
|
1
|
-
export async function prepareMfaPkce(appId) {
|
|
2
|
-
const encode = (value) => btoa(String.fromCharCode(...value)).replace(/\+/g, '-').replace(/\//g, '_').replace(/=+$/, '');
|
|
3
|
-
const verifier = encode(crypto.getRandomValues(new Uint8Array(32)));
|
|
4
|
-
sessionStorage.setItem(`app-mfa-pkce:${appId}`, verifier);
|
|
5
|
-
return encode(new Uint8Array(await crypto.subtle.digest('SHA-256', new TextEncoder().encode(verifier))));
|
|
6
|
-
}
|
|
7
|
-
export function createMfaModule(axios, appId, setToken) {
|
|
8
|
-
const post = async (challenge, path, payload = {}) => {
|
|
9
|
-
const response = await axios.post(`/apps/${appId}/auth/mfa${path}`, payload, {
|
|
10
|
-
headers: { Authorization: `Bearer ${challenge.mfa_session_token}` }, withCredentials: true,
|
|
11
|
-
});
|
|
12
|
-
const token = response.access_token;
|
|
13
|
-
if (token)
|
|
14
|
-
setToken(token);
|
|
15
|
-
return response;
|
|
16
|
-
};
|
|
17
|
-
return {
|
|
18
|
-
getStatus: () => axios.get(`/apps/${appId}/auth/mfa/status`),
|
|
19
|
-
resetForUser: appUserId => axios.post(`/apps/${appId}/auth/mfa/reset`, { app_user_id: appUserId }),
|
|
20
|
-
openSecurity(returnTo = '/') {
|
|
21
|
-
const target = new URL(returnTo, window.location.origin);
|
|
22
|
-
if (target.origin !== window.location.origin)
|
|
23
|
-
throw new Error('MFA must return to this app.');
|
|
24
|
-
window.location.href = `/auth/mfa?${new URLSearchParams({ security: '1', from_url: target.pathname + target.search + target.hash })}`;
|
|
25
|
-
},
|
|
26
|
-
setupTotp: challenge => post(challenge, '/totp/setup'),
|
|
27
|
-
sendSms: (challenge, phoneNumber) => post(challenge, '/sms/send-code', { phone_number: phoneNumber }),
|
|
28
|
-
enrollTotp: (challenge, code, rememberDevice = false) => post(challenge, '/totp/verify', { code, remember_device: rememberDevice }),
|
|
29
|
-
enrollSms: (challenge, code, rememberDevice = false) => post(challenge, '/sms/verify', { code, remember_device: rememberDevice }),
|
|
30
|
-
verify: (challenge, proof) => post(challenge, '/verify', proof),
|
|
31
|
-
verifyRecoveryCode: (challenge, code, rememberDevice = false) => post(challenge, '/verify-backup', { backup_code: code, remember_device: rememberDevice }),
|
|
32
|
-
resendSms: challenge => post(challenge, '/resend'),
|
|
33
|
-
async continueLogin(challenge, returnTo = '/') {
|
|
34
|
-
const target = new URL(returnTo, window.location.origin);
|
|
35
|
-
if (target.origin !== window.location.origin)
|
|
36
|
-
throw new Error('MFA must return to this app.');
|
|
37
|
-
const codeChallenge = await prepareMfaPkce(appId);
|
|
38
|
-
const handoff = await post(challenge, '/handoff', { code_challenge: codeChallenge });
|
|
39
|
-
const query = new URLSearchParams({ app_id: appId, mfa_code: handoff.code, from_url: target.pathname + target.search + target.hash });
|
|
40
|
-
window.location.href = `/auth/mfa?${query}`;
|
|
41
|
-
},
|
|
42
|
-
};
|
|
43
|
-
}
|