@getpara/user-management-client 3.3.0 → 3.5.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/cjs/client.js +59 -12
- package/dist/esm/client.js +59 -12
- package/dist/types/client.d.ts +29 -2
- package/package.json +3 -3
package/dist/cjs/client.js
CHANGED
|
@@ -99,34 +99,52 @@ const handleResponseSuccess = (response) => {
|
|
|
99
99
|
}
|
|
100
100
|
throw new import_error.ParaApiError("Invalid status code");
|
|
101
101
|
};
|
|
102
|
+
const UNKNOWN_ERROR_MESSAGE = "Unknown error";
|
|
103
|
+
const hasUsableString = (value) => typeof value === "string" && value.trim().length > 0;
|
|
104
|
+
const getFallbackErrorMessage = (error) => {
|
|
105
|
+
if (hasUsableString(error == null ? void 0 : error.message)) return error.message;
|
|
106
|
+
if (hasUsableString(error == null ? void 0 : error.code)) return error.code;
|
|
107
|
+
return UNKNOWN_ERROR_MESSAGE;
|
|
108
|
+
};
|
|
109
|
+
const throwParaApiError = (message, code, status, responseURL, data, cause) => {
|
|
110
|
+
const paraApiError = new import_error.ParaApiError(message, code, status, responseURL, data);
|
|
111
|
+
if (cause !== void 0) paraApiError.cause = cause;
|
|
112
|
+
throw paraApiError;
|
|
113
|
+
};
|
|
102
114
|
const handleResponseError = (error) => {
|
|
103
|
-
var _a,
|
|
115
|
+
var _a, _c, _d;
|
|
104
116
|
if (error === null) throw new import_error.ParaApiError("Error is null");
|
|
105
117
|
if (import_axios.default.isAxiosError(error)) {
|
|
106
118
|
const data = (_a = error.response) == null ? void 0 : _a.data;
|
|
107
|
-
let message =
|
|
119
|
+
let message = hasUsableString(data) ? data : getFallbackErrorMessage(error);
|
|
108
120
|
let serverCode;
|
|
109
121
|
let serverData;
|
|
110
122
|
if (data && typeof data === "object") {
|
|
111
123
|
const body = data;
|
|
112
|
-
if (
|
|
124
|
+
if (hasUsableString(body.message)) message = body.message;
|
|
113
125
|
serverCode = body.code;
|
|
114
|
-
|
|
126
|
+
if (body.data && typeof body.data === "object") {
|
|
127
|
+
serverData = body.data;
|
|
128
|
+
} else {
|
|
129
|
+
const _b = body, { message: _message, code: _code } = _b, rest = __objRest(_b, ["message", "code"]);
|
|
130
|
+
serverData = Object.keys(rest).length > 0 ? rest : void 0;
|
|
131
|
+
}
|
|
115
132
|
}
|
|
116
133
|
if (error.code === "ERR_NETWORK") {
|
|
117
134
|
message = "Connection error";
|
|
118
135
|
} else if (error.code === "ERR_CANCELED") {
|
|
119
136
|
message = "Connection canceled";
|
|
120
137
|
}
|
|
121
|
-
|
|
138
|
+
throwParaApiError(
|
|
122
139
|
message,
|
|
123
140
|
serverCode != null ? serverCode : error.code,
|
|
124
|
-
(
|
|
125
|
-
(
|
|
126
|
-
serverData
|
|
141
|
+
(_c = error.response) == null ? void 0 : _c.status,
|
|
142
|
+
(_d = error.request) == null ? void 0 : _d.responseURL,
|
|
143
|
+
serverData,
|
|
144
|
+
error
|
|
127
145
|
);
|
|
128
146
|
}
|
|
129
|
-
|
|
147
|
+
throwParaApiError(getFallbackErrorMessage(error), void 0, void 0, void 0, void 0, error);
|
|
130
148
|
};
|
|
131
149
|
const isRetryableError = (error) => {
|
|
132
150
|
var _a, _b, _c, _d;
|
|
@@ -143,7 +161,9 @@ class Client {
|
|
|
143
161
|
retrieveSessionCookie,
|
|
144
162
|
persistSessionCookie,
|
|
145
163
|
partnerConfigOverride,
|
|
146
|
-
staticTraceContext
|
|
164
|
+
staticTraceContext,
|
|
165
|
+
httpAgent,
|
|
166
|
+
httpsAgent
|
|
147
167
|
}) {
|
|
148
168
|
this.inFlightFaucetRequests = /* @__PURE__ */ new Map();
|
|
149
169
|
this.signUpOrLogIn = (body) => __async(this, null, function* () {
|
|
@@ -176,6 +196,33 @@ class Client {
|
|
|
176
196
|
const res = yield this.baseRequest.post("/users/verify-oauth");
|
|
177
197
|
return res.data;
|
|
178
198
|
});
|
|
199
|
+
// POST /internal/v1/auth/2fa/enroll
|
|
200
|
+
// Login-time 2FA enrollment (ENG-6906). Authenticated by the active session.
|
|
201
|
+
// Returns the otpauth URI to render as a QR plus the one-time backup codes.
|
|
202
|
+
this.enrollMfa = () => __async(this, null, function* () {
|
|
203
|
+
const res = yield this.baseRequest.post("/internal/v1/auth/2fa/enroll");
|
|
204
|
+
return res.data;
|
|
205
|
+
});
|
|
206
|
+
// POST /internal/v1/auth/2fa/verify
|
|
207
|
+
// Login-time 2FA verification (ENG-6906). On success the backend stamps the
|
|
208
|
+
// session so the keyshare/sign gate passes; callers should then re-poll the login
|
|
209
|
+
// status (verify-oauth) to advance to `stage:'done'`. A wrong code is a 401 with
|
|
210
|
+
// `code:'UNAUTHORIZED'` carrying the remaining attempt budget — we surface that as
|
|
211
|
+
// a typed `{ ok:false, attemptsRemaining }` rather than throwing, so the UI can
|
|
212
|
+
// re-prompt. Other failures (e.g. NOT_ENROLLED 400, network) still throw.
|
|
213
|
+
this.verifyMfa = (code) => __async(this, null, function* () {
|
|
214
|
+
try {
|
|
215
|
+
yield this.baseRequest.post("/internal/v1/auth/2fa/verify", { code });
|
|
216
|
+
return { ok: true };
|
|
217
|
+
} catch (error) {
|
|
218
|
+
const apiError = error;
|
|
219
|
+
if ((apiError == null ? void 0 : apiError.isParaApiError) && (apiError.code === "UNAUTHORIZED" || apiError.status === 401)) {
|
|
220
|
+
const data = apiError.data;
|
|
221
|
+
return { ok: false, attemptsRemaining: data == null ? void 0 : data.attemptsRemaining };
|
|
222
|
+
}
|
|
223
|
+
throw error;
|
|
224
|
+
}
|
|
225
|
+
});
|
|
179
226
|
this.loginExternalWallet = (_0) => __async(this, [_0], function* ({
|
|
180
227
|
externalWallet,
|
|
181
228
|
shouldTrackUser,
|
|
@@ -636,12 +683,12 @@ class Client {
|
|
|
636
683
|
// plain-text bodies for backward compat with older SDKs.
|
|
637
684
|
[import_shared.STRUCTURED_ERRORS_HEADER]: "1"
|
|
638
685
|
});
|
|
639
|
-
const axiosConfig = {
|
|
686
|
+
const axiosConfig = __spreadValues(__spreadValues({
|
|
640
687
|
baseURL: userManagementHost,
|
|
641
688
|
withCredentials: true,
|
|
642
689
|
timeout: 6e4,
|
|
643
690
|
headers
|
|
644
|
-
};
|
|
691
|
+
}, httpAgent ? { httpAgent } : {}), httpsAgent ? { httpsAgent } : {});
|
|
645
692
|
if (retrieveSessionCookie) {
|
|
646
693
|
const defaultTransformRequest = Array.isArray(import_axios.default.defaults.transformRequest) ? import_axios.default.defaults.transformRequest : [import_axios.default.defaults.transformRequest];
|
|
647
694
|
axiosConfig.transformRequest = [
|
package/dist/esm/client.js
CHANGED
|
@@ -30,34 +30,52 @@ const handleResponseSuccess = (response) => {
|
|
|
30
30
|
}
|
|
31
31
|
throw new ParaApiError("Invalid status code");
|
|
32
32
|
};
|
|
33
|
+
const UNKNOWN_ERROR_MESSAGE = "Unknown error";
|
|
34
|
+
const hasUsableString = (value) => typeof value === "string" && value.trim().length > 0;
|
|
35
|
+
const getFallbackErrorMessage = (error) => {
|
|
36
|
+
if (hasUsableString(error == null ? void 0 : error.message)) return error.message;
|
|
37
|
+
if (hasUsableString(error == null ? void 0 : error.code)) return error.code;
|
|
38
|
+
return UNKNOWN_ERROR_MESSAGE;
|
|
39
|
+
};
|
|
40
|
+
const throwParaApiError = (message, code, status, responseURL, data, cause) => {
|
|
41
|
+
const paraApiError = new ParaApiError(message, code, status, responseURL, data);
|
|
42
|
+
if (cause !== void 0) paraApiError.cause = cause;
|
|
43
|
+
throw paraApiError;
|
|
44
|
+
};
|
|
33
45
|
const handleResponseError = (error) => {
|
|
34
|
-
var _a,
|
|
46
|
+
var _a, _c, _d;
|
|
35
47
|
if (error === null) throw new ParaApiError("Error is null");
|
|
36
48
|
if (axios.isAxiosError(error)) {
|
|
37
49
|
const data = (_a = error.response) == null ? void 0 : _a.data;
|
|
38
|
-
let message =
|
|
50
|
+
let message = hasUsableString(data) ? data : getFallbackErrorMessage(error);
|
|
39
51
|
let serverCode;
|
|
40
52
|
let serverData;
|
|
41
53
|
if (data && typeof data === "object") {
|
|
42
54
|
const body = data;
|
|
43
|
-
if (
|
|
55
|
+
if (hasUsableString(body.message)) message = body.message;
|
|
44
56
|
serverCode = body.code;
|
|
45
|
-
|
|
57
|
+
if (body.data && typeof body.data === "object") {
|
|
58
|
+
serverData = body.data;
|
|
59
|
+
} else {
|
|
60
|
+
const _b = body, { message: _message, code: _code } = _b, rest = __objRest(_b, ["message", "code"]);
|
|
61
|
+
serverData = Object.keys(rest).length > 0 ? rest : void 0;
|
|
62
|
+
}
|
|
46
63
|
}
|
|
47
64
|
if (error.code === "ERR_NETWORK") {
|
|
48
65
|
message = "Connection error";
|
|
49
66
|
} else if (error.code === "ERR_CANCELED") {
|
|
50
67
|
message = "Connection canceled";
|
|
51
68
|
}
|
|
52
|
-
|
|
69
|
+
throwParaApiError(
|
|
53
70
|
message,
|
|
54
71
|
serverCode != null ? serverCode : error.code,
|
|
55
|
-
(
|
|
56
|
-
(
|
|
57
|
-
serverData
|
|
72
|
+
(_c = error.response) == null ? void 0 : _c.status,
|
|
73
|
+
(_d = error.request) == null ? void 0 : _d.responseURL,
|
|
74
|
+
serverData,
|
|
75
|
+
error
|
|
58
76
|
);
|
|
59
77
|
}
|
|
60
|
-
|
|
78
|
+
throwParaApiError(getFallbackErrorMessage(error), void 0, void 0, void 0, void 0, error);
|
|
61
79
|
};
|
|
62
80
|
const isRetryableError = (error) => {
|
|
63
81
|
var _a, _b, _c, _d;
|
|
@@ -74,7 +92,9 @@ class Client {
|
|
|
74
92
|
retrieveSessionCookie,
|
|
75
93
|
persistSessionCookie,
|
|
76
94
|
partnerConfigOverride,
|
|
77
|
-
staticTraceContext
|
|
95
|
+
staticTraceContext,
|
|
96
|
+
httpAgent,
|
|
97
|
+
httpsAgent
|
|
78
98
|
}) {
|
|
79
99
|
this.inFlightFaucetRequests = /* @__PURE__ */ new Map();
|
|
80
100
|
this.signUpOrLogIn = (body) => __async(this, null, function* () {
|
|
@@ -107,6 +127,33 @@ class Client {
|
|
|
107
127
|
const res = yield this.baseRequest.post("/users/verify-oauth");
|
|
108
128
|
return res.data;
|
|
109
129
|
});
|
|
130
|
+
// POST /internal/v1/auth/2fa/enroll
|
|
131
|
+
// Login-time 2FA enrollment (ENG-6906). Authenticated by the active session.
|
|
132
|
+
// Returns the otpauth URI to render as a QR plus the one-time backup codes.
|
|
133
|
+
this.enrollMfa = () => __async(this, null, function* () {
|
|
134
|
+
const res = yield this.baseRequest.post("/internal/v1/auth/2fa/enroll");
|
|
135
|
+
return res.data;
|
|
136
|
+
});
|
|
137
|
+
// POST /internal/v1/auth/2fa/verify
|
|
138
|
+
// Login-time 2FA verification (ENG-6906). On success the backend stamps the
|
|
139
|
+
// session so the keyshare/sign gate passes; callers should then re-poll the login
|
|
140
|
+
// status (verify-oauth) to advance to `stage:'done'`. A wrong code is a 401 with
|
|
141
|
+
// `code:'UNAUTHORIZED'` carrying the remaining attempt budget — we surface that as
|
|
142
|
+
// a typed `{ ok:false, attemptsRemaining }` rather than throwing, so the UI can
|
|
143
|
+
// re-prompt. Other failures (e.g. NOT_ENROLLED 400, network) still throw.
|
|
144
|
+
this.verifyMfa = (code) => __async(this, null, function* () {
|
|
145
|
+
try {
|
|
146
|
+
yield this.baseRequest.post("/internal/v1/auth/2fa/verify", { code });
|
|
147
|
+
return { ok: true };
|
|
148
|
+
} catch (error) {
|
|
149
|
+
const apiError = error;
|
|
150
|
+
if ((apiError == null ? void 0 : apiError.isParaApiError) && (apiError.code === "UNAUTHORIZED" || apiError.status === 401)) {
|
|
151
|
+
const data = apiError.data;
|
|
152
|
+
return { ok: false, attemptsRemaining: data == null ? void 0 : data.attemptsRemaining };
|
|
153
|
+
}
|
|
154
|
+
throw error;
|
|
155
|
+
}
|
|
156
|
+
});
|
|
110
157
|
this.loginExternalWallet = (_0) => __async(this, [_0], function* ({
|
|
111
158
|
externalWallet,
|
|
112
159
|
shouldTrackUser,
|
|
@@ -567,12 +614,12 @@ class Client {
|
|
|
567
614
|
// plain-text bodies for backward compat with older SDKs.
|
|
568
615
|
[STRUCTURED_ERRORS_HEADER]: "1"
|
|
569
616
|
});
|
|
570
|
-
const axiosConfig = {
|
|
617
|
+
const axiosConfig = __spreadValues(__spreadValues({
|
|
571
618
|
baseURL: userManagementHost,
|
|
572
619
|
withCredentials: true,
|
|
573
620
|
timeout: 6e4,
|
|
574
621
|
headers
|
|
575
|
-
};
|
|
622
|
+
}, httpAgent ? { httpAgent } : {}), httpsAgent ? { httpsAgent } : {});
|
|
576
623
|
if (retrieveSessionCookie) {
|
|
577
624
|
const defaultTransformRequest = Array.isArray(axios.defaults.transformRequest) ? axios.defaults.transformRequest : [axios.defaults.transformRequest];
|
|
578
625
|
axiosConfig.transformRequest = [
|
package/dist/types/client.d.ts
CHANGED
|
@@ -24,6 +24,13 @@ type ClientConfig = {
|
|
|
24
24
|
* interceptor that pulls from context.active().
|
|
25
25
|
*/
|
|
26
26
|
staticTraceContext?: Record<string, string>;
|
|
27
|
+
/**
|
|
28
|
+
* Node-only keep-alive agents, set by the server SDK so server-to-server
|
|
29
|
+
* callers reuse connections instead of re-handshaking TCP+TLS per request.
|
|
30
|
+
* Left undefined in the browser, where the runtime pools sockets itself.
|
|
31
|
+
*/
|
|
32
|
+
httpAgent?: unknown;
|
|
33
|
+
httpsAgent?: unknown;
|
|
27
34
|
};
|
|
28
35
|
interface createUserIdRes {
|
|
29
36
|
protocolId: string;
|
|
@@ -156,6 +163,24 @@ interface EncryptedWalletPrivateKey {
|
|
|
156
163
|
biometricPublicKey?: string;
|
|
157
164
|
passwordId?: string;
|
|
158
165
|
}
|
|
166
|
+
/**
|
|
167
|
+
* Login-time 2FA (MFA) enroll/verify response shapes (ENG-6906). The challenge
|
|
168
|
+
* payload itself (`MfaChallenge`) lives in @getpara/shared and flows through the
|
|
169
|
+
* login auth-state poll; these are the bodies of the two dedicated session-authed
|
|
170
|
+
* endpoints under /internal/v1/auth/2fa.
|
|
171
|
+
*/
|
|
172
|
+
export type EnrollMfaResponse = {
|
|
173
|
+
/** otpauth:// URI for the authenticator app. */
|
|
174
|
+
uri: string;
|
|
175
|
+
/** One-time backup codes, shown to the user exactly once at enrollment. */
|
|
176
|
+
backupCodes: string[];
|
|
177
|
+
};
|
|
178
|
+
export type VerifyMfaResult = {
|
|
179
|
+
ok: true;
|
|
180
|
+
} | {
|
|
181
|
+
ok: false;
|
|
182
|
+
attemptsRemaining?: number;
|
|
183
|
+
};
|
|
159
184
|
export type SDKType = 'WEB' | 'SERVER' | 'BRIDGE' | 'REACT_NATIVE';
|
|
160
185
|
export type VerifyTelegramRes = {
|
|
161
186
|
isValid: true;
|
|
@@ -168,12 +193,12 @@ export type VerifyTelegramRes = {
|
|
|
168
193
|
isValid: false;
|
|
169
194
|
};
|
|
170
195
|
export declare const handleResponseSuccess: (response: AxiosResponse<any, any>) => AxiosResponse<any, any>;
|
|
171
|
-
export declare const handleResponseError: (error: any) =>
|
|
196
|
+
export declare const handleResponseError: (error: any) => void;
|
|
172
197
|
export declare const isRetryableError: (error: AxiosError) => boolean;
|
|
173
198
|
declare class Client {
|
|
174
199
|
private baseRequest;
|
|
175
200
|
private inFlightFaucetRequests;
|
|
176
|
-
constructor({ userManagementHost, apiKey, partnerId, version, clientType, opts, retrieveSessionCookie, persistSessionCookie, partnerConfigOverride, staticTraceContext, }: ClientConfig);
|
|
201
|
+
constructor({ userManagementHost, apiKey, partnerId, version, clientType, opts, retrieveSessionCookie, persistSessionCookie, partnerConfigOverride, staticTraceContext, httpAgent, httpsAgent, }: ClientConfig);
|
|
177
202
|
signUpOrLogIn: (body: VerifiedAuth & VerificationEmailProps) => Promise<SignUpOrLogInResponse>;
|
|
178
203
|
/**
|
|
179
204
|
* @deprecated
|
|
@@ -185,6 +210,8 @@ declare class Client {
|
|
|
185
210
|
sessionLookupId?: string;
|
|
186
211
|
}) => Promise<VerifyTelegramResponse>;
|
|
187
212
|
verifyOAuth: () => Promise<VerifyThirdPartyAuth | null>;
|
|
213
|
+
enrollMfa: () => Promise<EnrollMfaResponse>;
|
|
214
|
+
verifyMfa: (code: string) => Promise<VerifyMfaResult>;
|
|
188
215
|
loginExternalWallet: ({ externalWallet, shouldTrackUser, chainId, uri, }: {
|
|
189
216
|
externalWallet: ExternalWalletInfo;
|
|
190
217
|
shouldTrackUser?: boolean;
|
package/package.json
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@getpara/user-management-client",
|
|
3
|
-
"version": "3.
|
|
3
|
+
"version": "3.5.0",
|
|
4
4
|
"dependencies": {
|
|
5
|
-
"@getpara/shared": "^1.
|
|
5
|
+
"@getpara/shared": "^1.23.0",
|
|
6
6
|
"@opentelemetry/api": "^1.9.1",
|
|
7
7
|
"axios": "^1.8.4",
|
|
8
8
|
"axios-retry": "^4.5.0",
|
|
@@ -22,7 +22,7 @@
|
|
|
22
22
|
"dist",
|
|
23
23
|
"package.json"
|
|
24
24
|
],
|
|
25
|
-
"gitHead": "
|
|
25
|
+
"gitHead": "2e70485f8f206ff50f58b339ebf0922fd259858f",
|
|
26
26
|
"main": "dist/cjs/index.js",
|
|
27
27
|
"module": "dist/esm/index.js",
|
|
28
28
|
"scripts": {
|