@rockerone/xprnkit 0.3.5 → 0.3.7
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/build/providers/XPRNProvider.d.ts +2 -1
- package/build/providers/XPRNProvider.js +15 -11
- package/build/services/identity-proof/create-identity-proof.js +1 -1
- package/build/services/identity-proof/types.d.ts +2 -1
- package/build/services/identity-proof/verify-identity-proof.js +2 -1
- package/package.json +1 -1
|
@@ -9,7 +9,8 @@ import { type IdentityProofStatus } from "../services/identity-proof";
|
|
|
9
9
|
*/
|
|
10
10
|
export type XPRNIdentityProof = {
|
|
11
11
|
actor: string;
|
|
12
|
-
|
|
12
|
+
/** Public key (optional - not available for browser/WebAuth wallets) */
|
|
13
|
+
publicKey?: string;
|
|
13
14
|
/** JWT token from the identity proof verification */
|
|
14
15
|
token?: string;
|
|
15
16
|
/** Additional data from the verification response */
|
|
@@ -61,6 +61,9 @@ export const XPRNProvider = ({ children, config, }) => {
|
|
|
61
61
|
const isRestoringRef = useRef(false);
|
|
62
62
|
const isAuthenticatingRef = useRef(false);
|
|
63
63
|
const isSwitchingSessionRef = useRef(false);
|
|
64
|
+
const sessionRef = useRef(null);
|
|
65
|
+
// Keep sessionRef in sync with session state
|
|
66
|
+
sessionRef.current = session;
|
|
64
67
|
// List stored sessions from proton-web-sdk localStorage
|
|
65
68
|
const listStoredSessions = useCallback(() => {
|
|
66
69
|
return sessionStorage.getLinkList(config.requesterAccount);
|
|
@@ -103,7 +106,6 @@ export const XPRNProvider = ({ children, config, }) => {
|
|
|
103
106
|
const newToken = result.token || storedEntry.identityProofToken;
|
|
104
107
|
setIdentityProof({
|
|
105
108
|
actor: actor,
|
|
106
|
-
publicKey: "",
|
|
107
109
|
token: newToken,
|
|
108
110
|
});
|
|
109
111
|
setIdentityProofStatus("success");
|
|
@@ -237,7 +239,9 @@ export const XPRNProvider = ({ children, config, }) => {
|
|
|
237
239
|
errorsStackRef.current.push(parseTransactionErrorMessage(message));
|
|
238
240
|
}, []);
|
|
239
241
|
const requestIdentityProof = useCallback(async (success, fail) => {
|
|
240
|
-
|
|
242
|
+
// Use ref to get the latest session value
|
|
243
|
+
const currentSession = sessionRef.current;
|
|
244
|
+
if (!currentSession) {
|
|
241
245
|
fail(new Error("No session available for identity proof"));
|
|
242
246
|
return;
|
|
243
247
|
}
|
|
@@ -253,7 +257,7 @@ export const XPRNProvider = ({ children, config, }) => {
|
|
|
253
257
|
try {
|
|
254
258
|
// Step 1: Sign with wallet
|
|
255
259
|
setIdentityProofStatus("signing");
|
|
256
|
-
const proof = await createIdentityProof(
|
|
260
|
+
const proof = await createIdentityProof(currentSession);
|
|
257
261
|
// Step 2: Verify with backend
|
|
258
262
|
setIdentityProofStatus("verifying");
|
|
259
263
|
const verifyRes = await verifyIdentityProof(proof, { createUrl: identityProofConfig.createUrl, headers: identityProofConfig.headers });
|
|
@@ -268,9 +272,9 @@ export const XPRNProvider = ({ children, config, }) => {
|
|
|
268
272
|
setIdentityProofStatus("success");
|
|
269
273
|
// Save token to storage
|
|
270
274
|
if (verifyRes.token) {
|
|
271
|
-
const actor =
|
|
272
|
-
const permission =
|
|
273
|
-
const chainId =
|
|
275
|
+
const actor = currentSession.auth.actor.toString();
|
|
276
|
+
const permission = currentSession.auth.permission.toString();
|
|
277
|
+
const chainId = currentSession.chainId.toString();
|
|
274
278
|
sessionStorage.updateIdentityProofToken(config.requesterAccount, { actor, permission }, chainId, verifyRes.token);
|
|
275
279
|
}
|
|
276
280
|
success(identityProofData);
|
|
@@ -282,7 +286,7 @@ export const XPRNProvider = ({ children, config, }) => {
|
|
|
282
286
|
finally {
|
|
283
287
|
isAuthenticatingRef.current = false;
|
|
284
288
|
}
|
|
285
|
-
}, [
|
|
289
|
+
}, [identityProofConfig, config.requesterAccount]);
|
|
286
290
|
// Legacy alias
|
|
287
291
|
const authenticate = requestIdentityProof;
|
|
288
292
|
// Validate stored token silently
|
|
@@ -321,7 +325,6 @@ export const XPRNProvider = ({ children, config, }) => {
|
|
|
321
325
|
const newToken = result.token || storedToken;
|
|
322
326
|
setIdentityProof({
|
|
323
327
|
actor,
|
|
324
|
-
publicKey: "", // We don't have public key from stored token
|
|
325
328
|
token: newToken,
|
|
326
329
|
});
|
|
327
330
|
setIdentityProofStatus("success");
|
|
@@ -359,7 +362,8 @@ export const XPRNProvider = ({ children, config, }) => {
|
|
|
359
362
|
const chainId = session.chainId.toString();
|
|
360
363
|
// Check if there's a stored token and try to validate it
|
|
361
364
|
const storedEntry = sessionStorage.get(config.requesterAccount, { actor, permission }, chainId);
|
|
362
|
-
|
|
365
|
+
const hasStoredToken = storedEntry?.identityProofToken && typeof storedEntry.identityProofToken === 'string' && storedEntry.identityProofToken.length > 0;
|
|
366
|
+
if (hasStoredToken && identityProofConfig.validationUrl) {
|
|
363
367
|
// Try to validate stored token silently
|
|
364
368
|
validateStoredToken(actor, permission, chainId).then(isValid => {
|
|
365
369
|
if (!isValid && (identityProofConfig.enforceOnConnect || identityProofConfig.required)) {
|
|
@@ -368,8 +372,8 @@ export const XPRNProvider = ({ children, config, }) => {
|
|
|
368
372
|
}
|
|
369
373
|
});
|
|
370
374
|
}
|
|
371
|
-
else if (identityProofConfig.enforceOnConnect) {
|
|
372
|
-
// No stored token but
|
|
375
|
+
else if (identityProofConfig.enforceOnConnect || identityProofConfig.required) {
|
|
376
|
+
// No stored token (or no validation URL) but identity proof is required - trigger auth flow
|
|
373
377
|
requestIdentityProof(() => { }, () => { });
|
|
374
378
|
}
|
|
375
379
|
}, [session, identityProof, identityProofConfig, config.requesterAccount, validateStoredToken, requestIdentityProof]);
|
|
@@ -34,11 +34,11 @@ export async function createIdentityProof(session, options) {
|
|
|
34
34
|
throw new DOMException("Aborted", "AbortError");
|
|
35
35
|
}
|
|
36
36
|
// Build the identity proof
|
|
37
|
+
// Note: publicKey may not be available for browser/WebAuth wallets
|
|
37
38
|
const proof = {
|
|
38
39
|
signer: {
|
|
39
40
|
actor,
|
|
40
41
|
permission,
|
|
41
|
-
publicKey: session.publicKey.toString(),
|
|
42
42
|
},
|
|
43
43
|
transaction: txResult.resolvedTransaction,
|
|
44
44
|
signatures: txResult.signatures.map(sig => sig.toString()),
|
|
@@ -5,7 +5,8 @@ import type { LinkSession } from "@proton/web-sdk";
|
|
|
5
5
|
export type IdentityProofSigner = {
|
|
6
6
|
actor: string;
|
|
7
7
|
permission: string;
|
|
8
|
-
|
|
8
|
+
/** Public key (optional - not available for browser/WebAuth wallets) */
|
|
9
|
+
publicKey?: string;
|
|
9
10
|
};
|
|
10
11
|
/**
|
|
11
12
|
* Identity proof generated from wallet signing
|
|
@@ -34,11 +34,12 @@ export async function verifyIdentityProof(proof, config, options) {
|
|
|
34
34
|
}
|
|
35
35
|
const url = getCreateUrl(config);
|
|
36
36
|
// Build request body
|
|
37
|
+
// Note: public_key is optional (not available for browser/WebAuth wallets)
|
|
37
38
|
const requestBody = {
|
|
38
39
|
signer: {
|
|
39
40
|
actor: proof.signer.actor,
|
|
40
41
|
permission: proof.signer.permission,
|
|
41
|
-
public_key: proof.signer.publicKey,
|
|
42
|
+
...(proof.signer.publicKey ? { public_key: proof.signer.publicKey } : {}),
|
|
42
43
|
},
|
|
43
44
|
transaction: proof.transaction,
|
|
44
45
|
signatures: proof.signatures,
|