ribaunt 0.1.0 → 0.1.2

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.
@@ -8,10 +8,6 @@ exports.solveChallenge = solveChallenge;
8
8
  exports.verifySolution = verifySolution;
9
9
  const crypto_1 = __importDefault(require("crypto"));
10
10
  const jsonwebtoken_1 = __importDefault(require("jsonwebtoken"));
11
- const secret = process.env.RIBAUNT_SECRET;
12
- if (!secret) {
13
- throw new Error('RIBAUNT_SECRET environment variable is not set!');
14
- }
15
11
  function generateChallenge(length = 8) {
16
12
  const buffer = crypto_1.default.randomBytes(length);
17
13
  return buffer.toString('base64').slice(0, length);
@@ -23,8 +19,15 @@ function createChallengePayload(difficulty, ttlSeconds) {
23
19
  expires: Math.floor(Date.now() / 1000) + ttlSeconds,
24
20
  };
25
21
  }
22
+ function getSecret() {
23
+ const secret = process.env.RIBAUNT_SECRET;
24
+ if (!secret) {
25
+ throw new Error('RIBAUNT_SECRET environment variable is not set!');
26
+ }
27
+ return secret;
28
+ }
26
29
  function signChallenge(payload) {
27
- return jsonwebtoken_1.default.sign(payload, secret);
30
+ return jsonwebtoken_1.default.sign(payload, getSecret());
28
31
  }
29
32
  function assertValidAmount(amount) {
30
33
  if (!Number.isFinite(amount)) {
@@ -36,6 +39,26 @@ function assertValidAmount(amount) {
36
39
  }
37
40
  return normalized;
38
41
  }
42
+ function assertValidDifficulty(difficulty) {
43
+ if (!Number.isFinite(difficulty)) {
44
+ throw new Error('Challenge difficulty must be a finite number');
45
+ }
46
+ const normalized = Math.floor(difficulty);
47
+ if (normalized < 1) {
48
+ throw new Error('Challenge difficulty must be at least 1');
49
+ }
50
+ return normalized;
51
+ }
52
+ function assertValidTtl(ttlSeconds) {
53
+ if (!Number.isFinite(ttlSeconds)) {
54
+ throw new Error('Challenge TTL must be a finite number');
55
+ }
56
+ const normalized = Math.floor(ttlSeconds);
57
+ if (normalized < 1) {
58
+ throw new Error('Challenge TTL must be at least 1 second');
59
+ }
60
+ return normalized;
61
+ }
39
62
  function createSingleChallenge(difficulty, ttlSeconds) {
40
63
  const payload = createChallengePayload(difficulty, ttlSeconds);
41
64
  return signChallenge(payload);
@@ -49,8 +72,10 @@ function createSingleChallenge(difficulty, ttlSeconds) {
49
72
  * @returns An array of JWT challenge tokens
50
73
  */
51
74
  function createChallenge(difficulty = 5, amount = 4, ttlSeconds = 30) {
75
+ const normalizedDifficulty = assertValidDifficulty(difficulty);
52
76
  const normalizedAmount = assertValidAmount(amount);
53
- const challenges = Array.from({ length: normalizedAmount }, () => createSingleChallenge(difficulty, ttlSeconds));
77
+ const normalizedTtl = assertValidTtl(ttlSeconds);
78
+ const challenges = Array.from({ length: normalizedAmount }, () => createSingleChallenge(normalizedDifficulty, normalizedTtl));
54
79
  return challenges;
55
80
  }
56
81
  function solveSingleChallenge(token) {
@@ -81,7 +106,7 @@ function verifySingleSolution(token, nonce) {
81
106
  return false;
82
107
  }
83
108
  try {
84
- const payload = jsonwebtoken_1.default.verify(token, secret);
109
+ const payload = jsonwebtoken_1.default.verify(token, getSecret());
85
110
  const now = Math.floor(Date.now() / 1000);
86
111
  if (payload.expires < now)
87
112
  return false;
@@ -0,0 +1,31 @@
1
+ export type ChallengeToken = string;
2
+ export interface ChallengeSolution {
3
+ nonce: string;
4
+ hash: string;
5
+ }
6
+ /**
7
+ * Creates one or more PoW challenges and returns them as signed JWT tokens.
8
+ *
9
+ * @param difficulty - Number of leading zeros required in the hash (default 6)
10
+ * @param amount - Number of challenges to create (default 4)
11
+ * @param ttlSeconds - Time to live for each challenge in seconds (default 30)
12
+ * @returns An array of JWT challenge tokens
13
+ */
14
+ export declare function createChallenge(difficulty?: number, amount?: number, ttlSeconds?: number): ChallengeToken[];
15
+ /**
16
+ * Solves one or more PoW challenges encoded in JWT tokens.
17
+ *
18
+ * @param token - The JWT challenge token or an array of tokens
19
+ * @returns The nonce/hash pair for single input or an array of them for multiple tokens
20
+ */
21
+ export declare function solveChallenge(token: ChallengeToken): ChallengeSolution | undefined;
22
+ export declare function solveChallenge(token: ChallengeToken[]): ChallengeSolution[] | undefined;
23
+ /**
24
+ * Verifies a PoW solution returned by the client.
25
+ *
26
+ * @param token - The original JWT issued as the challenge (single token or array of tokens)
27
+ * @param nonce - The nonce/answer submitted by the client (single nonce, array of nonces, or array of solution objects)
28
+ * @returns true only if every provided solution is valid; otherwise false
29
+ */
30
+ export declare function verifySolution(token: ChallengeToken | ChallengeToken[], nonce: number | string | Array<number | string> | ChallengeSolution | ChallengeSolution[]): boolean;
31
+ //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"AAeA,MAAM,MAAM,cAAc,GAAG,MAAM,CAAC;AAEpC,MAAM,WAAW,iBAAiB;IAChC,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,EAAE,MAAM,CAAC;CACd;AAqCD;;;;;;;GAOG;AACH,wBAAgB,eAAe,CAC7B,UAAU,GAAE,MAAU,EACtB,MAAM,GAAE,MAAU,EAClB,UAAU,GAAE,MAAW,GACtB,cAAc,EAAE,CAKlB;AAoDD;;;;;GAKG;AACH,wBAAgB,cAAc,CAAC,KAAK,EAAE,cAAc,GAAG,iBAAiB,GAAG,SAAS,CAAC;AACrF,wBAAgB,cAAc,CAAC,KAAK,EAAE,cAAc,EAAE,GAAG,iBAAiB,EAAE,GAAG,SAAS,CAAC;AAuBzF;;;;;;GAMG;AACH,wBAAgB,cAAc,CAC5B,KAAK,EAAE,cAAc,GAAG,cAAc,EAAE,EACxC,KAAK,EAAE,MAAM,GAAG,MAAM,GAAG,KAAK,CAAC,MAAM,GAAG,MAAM,CAAC,GAAG,iBAAiB,GAAG,iBAAiB,EAAE,GACxF,OAAO,CAqDT"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"AASA,MAAM,MAAM,cAAc,GAAG,MAAM,CAAC;AAEpC,MAAM,WAAW,iBAAiB;IAChC,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,EAAE,MAAM,CAAC;CACd;AAyED;;;;;;;GAOG;AACH,wBAAgB,eAAe,CAC7B,UAAU,GAAE,MAAU,EACtB,MAAM,GAAE,MAAU,EAClB,UAAU,GAAE,MAAW,GACtB,cAAc,EAAE,CAUlB;AAoDD;;;;;GAKG;AACH,wBAAgB,cAAc,CAAC,KAAK,EAAE,cAAc,GAAG,iBAAiB,GAAG,SAAS,CAAC;AACrF,wBAAgB,cAAc,CAAC,KAAK,EAAE,cAAc,EAAE,GAAG,iBAAiB,EAAE,GAAG,SAAS,CAAC;AAuBzF;;;;;;GAMG;AACH,wBAAgB,cAAc,CAC5B,KAAK,EAAE,cAAc,GAAG,cAAc,EAAE,EACxC,KAAK,EAAE,MAAM,GAAG,MAAM,GAAG,KAAK,CAAC,MAAM,GAAG,MAAM,CAAC,GAAG,iBAAiB,GAAG,iBAAiB,EAAE,GACxF,OAAO,CAqDT"}
@@ -0,0 +1,200 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.createChallenge = createChallenge;
7
+ exports.solveChallenge = solveChallenge;
8
+ exports.verifySolution = verifySolution;
9
+ const crypto_1 = __importDefault(require("crypto"));
10
+ const jsonwebtoken_1 = __importDefault(require("jsonwebtoken"));
11
+ function generateChallenge(length = 8) {
12
+ const buffer = crypto_1.default.randomBytes(length);
13
+ return buffer.toString('base64').slice(0, length);
14
+ }
15
+ function createChallengePayload(difficulty, ttlSeconds) {
16
+ return {
17
+ challenge: generateChallenge(),
18
+ difficulty,
19
+ expires: Math.floor(Date.now() / 1000) + ttlSeconds,
20
+ };
21
+ }
22
+ function getSecret() {
23
+ const secret = process.env.RIBAUNT_SECRET;
24
+ if (!secret) {
25
+ throw new Error('RIBAUNT_SECRET environment variable is not set!');
26
+ }
27
+ return secret;
28
+ }
29
+ function signChallenge(payload) {
30
+ return jsonwebtoken_1.default.sign(payload, getSecret());
31
+ }
32
+ function assertValidAmount(amount) {
33
+ if (!Number.isFinite(amount)) {
34
+ throw new Error('Challenge amount must be a finite number');
35
+ }
36
+ const normalized = Math.floor(amount);
37
+ if (normalized < 1) {
38
+ throw new Error('Challenge amount must be at least 1');
39
+ }
40
+ return normalized;
41
+ }
42
+ function assertValidDifficulty(difficulty) {
43
+ if (!Number.isFinite(difficulty)) {
44
+ throw new Error('Challenge difficulty must be a finite number');
45
+ }
46
+ const normalized = Math.floor(difficulty);
47
+ if (normalized < 1) {
48
+ throw new Error('Challenge difficulty must be at least 1');
49
+ }
50
+ return normalized;
51
+ }
52
+ function assertValidTtl(ttlSeconds) {
53
+ if (!Number.isFinite(ttlSeconds)) {
54
+ throw new Error('Challenge TTL must be a finite number');
55
+ }
56
+ const normalized = Math.floor(ttlSeconds);
57
+ if (normalized < 1) {
58
+ throw new Error('Challenge TTL must be at least 1 second');
59
+ }
60
+ return normalized;
61
+ }
62
+ function createSingleChallenge(difficulty, ttlSeconds) {
63
+ const payload = createChallengePayload(difficulty, ttlSeconds);
64
+ return signChallenge(payload);
65
+ }
66
+ /**
67
+ * Creates one or more PoW challenges and returns them as signed JWT tokens.
68
+ *
69
+ * @param difficulty - Number of leading zeros required in the hash (default 6)
70
+ * @param amount - Number of challenges to create (default 4)
71
+ * @param ttlSeconds - Time to live for each challenge in seconds (default 30)
72
+ * @returns An array of JWT challenge tokens
73
+ */
74
+ function createChallenge(difficulty = 5, amount = 4, ttlSeconds = 30) {
75
+ const normalizedDifficulty = assertValidDifficulty(difficulty);
76
+ const normalizedAmount = assertValidAmount(amount);
77
+ const normalizedTtl = assertValidTtl(ttlSeconds);
78
+ const challenges = Array.from({ length: normalizedAmount }, () => createSingleChallenge(normalizedDifficulty, normalizedTtl));
79
+ return challenges;
80
+ }
81
+ function solveSingleChallenge(token) {
82
+ try {
83
+ const payload = jsonwebtoken_1.default.decode(token);
84
+ if (!payload)
85
+ return undefined;
86
+ const { challenge, difficulty } = payload;
87
+ const prefix = '0'.repeat(difficulty);
88
+ let nonce = 0;
89
+ while (true) {
90
+ const hash = crypto_1.default
91
+ .createHash('sha256')
92
+ .update(`${challenge}${nonce}`)
93
+ .digest('hex');
94
+ if (hash.startsWith(prefix)) {
95
+ return { nonce: String(nonce), hash };
96
+ }
97
+ nonce++;
98
+ }
99
+ }
100
+ catch (err) {
101
+ return undefined;
102
+ }
103
+ }
104
+ function verifySingleSolution(token, nonce) {
105
+ if (nonce === undefined || nonce === null) {
106
+ return false;
107
+ }
108
+ try {
109
+ const payload = jsonwebtoken_1.default.verify(token, getSecret());
110
+ const now = Math.floor(Date.now() / 1000);
111
+ if (payload.expires < now)
112
+ return false;
113
+ const nonceValue = typeof nonce === 'number' ? String(nonce) : nonce;
114
+ const hash = crypto_1.default
115
+ .createHash('sha256')
116
+ .update(`${payload.challenge}${nonceValue}`)
117
+ .digest('hex');
118
+ const prefix = '0'.repeat(payload.difficulty);
119
+ return hash.startsWith(prefix);
120
+ }
121
+ catch (err) {
122
+ return false;
123
+ }
124
+ }
125
+ function solveChallenge(token) {
126
+ if (Array.isArray(token)) {
127
+ const solutions = [];
128
+ for (const singleToken of token) {
129
+ const solution = solveSingleChallenge(singleToken);
130
+ if (!solution) {
131
+ return undefined;
132
+ }
133
+ solutions.push(solution);
134
+ }
135
+ return solutions;
136
+ }
137
+ const solution = solveSingleChallenge(token);
138
+ return solution;
139
+ }
140
+ /**
141
+ * Verifies a PoW solution returned by the client.
142
+ *
143
+ * @param token - The original JWT issued as the challenge (single token or array of tokens)
144
+ * @param nonce - The nonce/answer submitted by the client (single nonce, array of nonces, or array of solution objects)
145
+ * @returns true only if every provided solution is valid; otherwise false
146
+ */
147
+ function verifySolution(token, nonce) {
148
+ if (Array.isArray(token)) {
149
+ let nonces;
150
+ if (Array.isArray(nonce)) {
151
+ if (nonce.length !== token.length) {
152
+ return false;
153
+ }
154
+ if (nonce.length > 0 && typeof nonce[0] === 'object' && 'nonce' in nonce[0]) {
155
+ nonces = nonce.map(s => s.nonce);
156
+ }
157
+ else {
158
+ nonces = nonce;
159
+ }
160
+ }
161
+ else {
162
+ return false;
163
+ }
164
+ for (let index = 0; index < token.length; index++) {
165
+ const challengeToken = token[index];
166
+ const nonceEntry = nonces[index];
167
+ if (challengeToken === undefined || nonceEntry === undefined) {
168
+ return false;
169
+ }
170
+ if (!verifySingleSolution(challengeToken, nonceEntry)) {
171
+ return false;
172
+ }
173
+ }
174
+ return true;
175
+ }
176
+ let effectiveNonce;
177
+ if (Array.isArray(nonce)) {
178
+ if (nonce.length === 0) {
179
+ return false;
180
+ }
181
+ if (typeof nonce[0] === 'object' && 'nonce' in nonce[0]) {
182
+ effectiveNonce = nonce[0].nonce;
183
+ }
184
+ else {
185
+ effectiveNonce = nonce[0];
186
+ }
187
+ }
188
+ else if (typeof nonce === 'object' && 'nonce' in nonce) {
189
+ effectiveNonce = nonce.nonce;
190
+ }
191
+ else {
192
+ effectiveNonce = nonce;
193
+ }
194
+ if (effectiveNonce === undefined) {
195
+ return false;
196
+ }
197
+ const result = verifySingleSolution(token, effectiveNonce);
198
+ return result;
199
+ }
200
+ //# sourceMappingURL=index.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,3 @@
1
+ {
2
+ "type": "commonjs"
3
+ }
@@ -1 +1 @@
1
- {"version":3,"file":"solver.d.ts","sourceRoot":"","sources":["../../src/solver.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,MAAM,WAAW,iBAAiB;IAChC,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,EAAE,MAAM,CAAC;CACd;AAkCD;;GAEG;AACH,wBAAsB,oBAAoB,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,iBAAiB,GAAG,SAAS,CAAC,CA0BhG;AAED;;GAEG;AACH,wBAAsB,cAAc,CAClC,MAAM,EAAE,MAAM,EAAE,EAChB,UAAU,CAAC,EAAE,CAAC,QAAQ,EAAE,MAAM,KAAK,IAAI,GACtC,OAAO,CAAC,iBAAiB,EAAE,CAAC,CAwB9B"}
1
+ {"version":3,"file":"solver.d.ts","sourceRoot":"","sources":["../../src/solver.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,MAAM,WAAW,iBAAiB;IAChC,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,EAAE,MAAM,CAAC;CACd;AAgDD;;GAEG;AACH,wBAAsB,oBAAoB,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,iBAAiB,GAAG,SAAS,CAAC,CAsBhG;AAED;;GAEG;AACH,wBAAsB,cAAc,CAClC,MAAM,EAAE,MAAM,EAAE,EAChB,UAAU,CAAC,EAAE,CAAC,QAAQ,EAAE,MAAM,KAAK,IAAI,GACtC,OAAO,CAAC,iBAAiB,EAAE,CAAC,CAwB9B"}
@@ -13,7 +13,9 @@ function decodeJWT(token) {
13
13
  const parts = token.split('.');
14
14
  if (parts.length !== 3 || !parts[1])
15
15
  return null;
16
- const payload = JSON.parse(atob(parts[1].replace(/-/g, '+').replace(/_/g, '/')));
16
+ const normalizedPayload = parts[1].replace(/-/g, '+').replace(/_/g, '/');
17
+ const paddedPayload = normalizedPayload.padEnd(normalizedPayload.length + ((4 - (normalizedPayload.length % 4)) % 4), '=');
18
+ const payload = JSON.parse(atob(paddedPayload));
17
19
  return payload;
18
20
  }
19
21
  catch {
@@ -24,6 +26,12 @@ function decodeJWT(token) {
24
26
  * SHA-256 hash using Web Crypto API
25
27
  */
26
28
  async function sha256(message) {
29
+ if (typeof TextEncoder === 'undefined') {
30
+ throw new Error('TextEncoder is unavailable in this browser environment');
31
+ }
32
+ if (!globalThis.crypto?.subtle) {
33
+ throw new Error('Web Crypto API is unavailable. Use HTTPS or localhost.');
34
+ }
27
35
  const msgBuffer = new TextEncoder().encode(message);
28
36
  const hashBuffer = await crypto.subtle.digest('SHA-256', msgBuffer);
29
37
  const hashArray = Array.from(new Uint8Array(hashBuffer));
@@ -34,27 +42,22 @@ async function sha256(message) {
34
42
  * Solve a single challenge token (browser-compatible)
35
43
  */
36
44
  async function solveSingleChallenge(token) {
37
- try {
38
- const payload = decodeJWT(token);
39
- if (!payload)
40
- return undefined;
41
- const { challenge, difficulty } = payload;
42
- const prefix = '0'.repeat(difficulty);
43
- let nonce = 0;
44
- while (true) {
45
- const hash = await sha256(`${challenge}${nonce}`);
46
- if (hash.startsWith(prefix)) {
47
- return { nonce: String(nonce), hash };
48
- }
49
- nonce++;
50
- // Yield to prevent blocking the UI (every 1000 iterations)
51
- if (nonce % 1000 === 0) {
52
- await new Promise(resolve => setTimeout(resolve, 0));
53
- }
54
- }
55
- }
56
- catch (err) {
45
+ const payload = decodeJWT(token);
46
+ if (!payload)
57
47
  return undefined;
48
+ const { challenge, difficulty } = payload;
49
+ const prefix = '0'.repeat(difficulty);
50
+ let nonce = 0;
51
+ while (true) {
52
+ const hash = await sha256(`${challenge}${nonce}`);
53
+ if (hash.startsWith(prefix)) {
54
+ return { nonce: String(nonce), hash };
55
+ }
56
+ nonce++;
57
+ // Yield to prevent blocking the UI (every 1000 iterations)
58
+ if (nonce % 1000 === 0) {
59
+ await new Promise(resolve => setTimeout(resolve, 0));
60
+ }
58
61
  }
59
62
  }
60
63
  /**
@@ -1 +1 @@
1
- {"version":3,"file":"solver.js","sourceRoot":"","sources":["../../src/solver.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"solver.js","sourceRoot":"","sources":["../../src/solver.ts"],"names":[],"mappings":"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"}
@@ -1,6 +1,6 @@
1
1
  import React from 'react';
2
2
  import type { RibauntWidgetElement, WidgetState } from './widget.js';
3
- export interface RibauntWidgetProps extends Omit<React.HTMLAttributes<RibauntWidgetElement>, 'onError'> {
3
+ export interface RibauntWidgetProps extends Omit<React.HTMLAttributes<RibauntWidgetElement>, 'onError' | 'onLoad'> {
4
4
  challengeEndpoint?: string;
5
5
  verifyEndpoint?: string;
6
6
  showWarning?: boolean | string;
@@ -15,6 +15,13 @@ export interface RibauntWidgetProps extends Omit<React.HTMLAttributes<RibauntWid
15
15
  onStateChange?: (detail: {
16
16
  state: WidgetState;
17
17
  }) => void;
18
+ onReady?: (detail: {
19
+ state: WidgetState;
20
+ }) => void;
21
+ onLoad?: (detail: {
22
+ state: WidgetState;
23
+ }) => void;
24
+ onEvent?: (type: 'verify' | 'error' | 'state-change' | 'ready', detail: unknown) => void;
18
25
  }
19
26
  export interface RibauntWidgetHandle {
20
27
  reset: () => void;
@@ -1 +1 @@
1
- {"version":3,"file":"widget-react.d.ts","sourceRoot":"","sources":["../../src/widget-react.tsx"],"names":[],"mappings":"AAEA,OAAO,KAAuE,MAAM,OAAO,CAAC;AAC5F,OAAO,KAAK,EAAE,oBAAoB,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;AAErE,MAAM,WAAW,kBAAmB,SAAQ,IAAI,CAAC,KAAK,CAAC,cAAc,CAAC,oBAAoB,CAAC,EAAE,SAAS,CAAC;IACrG,iBAAiB,CAAC,EAAE,MAAM,CAAC;IAC3B,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,WAAW,CAAC,EAAE,OAAO,GAAG,MAAM,CAAC;IAC/B,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,QAAQ,CAAC,EAAE,OAAO,GAAG,MAAM,CAAC;IAC5B,QAAQ,CAAC,EAAE,CAAC,MAAM,EAAE;QAAE,SAAS,EAAE,GAAG,EAAE,CAAA;KAAE,KAAK,IAAI,CAAC;IAClD,OAAO,CAAC,EAAE,CAAC,MAAM,EAAE;QAAE,KAAK,EAAE,MAAM,CAAA;KAAE,KAAK,IAAI,CAAC;IAC9C,aAAa,CAAC,EAAE,CAAC,MAAM,EAAE;QAAE,KAAK,EAAE,WAAW,CAAA;KAAE,KAAK,IAAI,CAAC;CAC1D;AAED,MAAM,WAAW,mBAAmB;IAClC,KAAK,EAAE,MAAM,IAAI,CAAC;IAClB,QAAQ,EAAE,MAAM,WAAW,GAAG,EAAE,CAAC;IACjC,iBAAiB,EAAE,MAAM,IAAI,CAAC;CAC/B;AAED;;;GAGG;AACH,eAAO,MAAM,aAAa,gGAoGzB,CAAC;AAIF,eAAe,aAAa,CAAC"}
1
+ {"version":3,"file":"widget-react.d.ts","sourceRoot":"","sources":["../../src/widget-react.tsx"],"names":[],"mappings":"AAEA,OAAO,KAAuE,MAAM,OAAO,CAAC;AAC5F,OAAO,KAAK,EAAE,oBAAoB,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;AAErE,MAAM,WAAW,kBAAmB,SAAQ,IAAI,CAAC,KAAK,CAAC,cAAc,CAAC,oBAAoB,CAAC,EAAE,SAAS,GAAG,QAAQ,CAAC;IAChH,iBAAiB,CAAC,EAAE,MAAM,CAAC;IAC3B,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,WAAW,CAAC,EAAE,OAAO,GAAG,MAAM,CAAC;IAC/B,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,QAAQ,CAAC,EAAE,OAAO,GAAG,MAAM,CAAC;IAC5B,QAAQ,CAAC,EAAE,CAAC,MAAM,EAAE;QAAE,SAAS,EAAE,GAAG,EAAE,CAAA;KAAE,KAAK,IAAI,CAAC;IAClD,OAAO,CAAC,EAAE,CAAC,MAAM,EAAE;QAAE,KAAK,EAAE,MAAM,CAAA;KAAE,KAAK,IAAI,CAAC;IAC9C,aAAa,CAAC,EAAE,CAAC,MAAM,EAAE;QAAE,KAAK,EAAE,WAAW,CAAA;KAAE,KAAK,IAAI,CAAC;IACzD,OAAO,CAAC,EAAE,CAAC,MAAM,EAAE;QAAE,KAAK,EAAE,WAAW,CAAA;KAAE,KAAK,IAAI,CAAC;IACnD,MAAM,CAAC,EAAE,CAAC,MAAM,EAAE;QAAE,KAAK,EAAE,WAAW,CAAA;KAAE,KAAK,IAAI,CAAC;IAClD,OAAO,CAAC,EAAE,CAAC,IAAI,EAAE,QAAQ,GAAG,OAAO,GAAG,cAAc,GAAG,OAAO,EAAE,MAAM,EAAE,OAAO,KAAK,IAAI,CAAC;CAC1F;AAED,MAAM,WAAW,mBAAmB;IAClC,KAAK,EAAE,MAAM,IAAI,CAAC;IAClB,QAAQ,EAAE,MAAM,WAAW,GAAG,EAAE,CAAC;IACjC,iBAAiB,EAAE,MAAM,IAAI,CAAC;CAC/B;AAsCD;;;GAGG;AACH,eAAO,MAAM,aAAa,gGAsJzB,CAAC;AAIF,eAAe,aAAa,CAAC"}
@@ -37,14 +37,38 @@ Object.defineProperty(exports, "__esModule", { value: true });
37
37
  exports.RibauntWidget = void 0;
38
38
  const jsx_runtime_1 = require("react/jsx-runtime");
39
39
  const react_1 = require("react");
40
+ function syncAttribute(element, name, value) {
41
+ if (value === undefined || value === false || value === 'false') {
42
+ element.removeAttribute(name);
43
+ return;
44
+ }
45
+ element.setAttribute(name, typeof value === 'boolean' ? 'true' : String(value));
46
+ }
47
+ function syncWidgetProps(element, { challengeEndpoint, verifyEndpoint, showWarning, warningMessage, disabled, }) {
48
+ syncAttribute(element, 'challenge-endpoint', challengeEndpoint);
49
+ syncAttribute(element, 'verify-endpoint', verifyEndpoint);
50
+ syncAttribute(element, 'show-warning', showWarning);
51
+ syncAttribute(element, 'warning-message', warningMessage);
52
+ syncAttribute(element, 'disabled', disabled);
53
+ }
40
54
  /**
41
55
  * React wrapper for the Ribaunt Web Component.
42
56
  * Safely loads the web component dynamically, avoiding Next.js SSR issues.
43
57
  */
44
- exports.RibauntWidget = (0, react_1.forwardRef)(({ challengeEndpoint, verifyEndpoint, showWarning, warningMessage, disabled, onVerify, onError, onStateChange, ...props }, ref) => {
58
+ exports.RibauntWidget = (0, react_1.forwardRef)(({ challengeEndpoint, verifyEndpoint, showWarning, warningMessage, disabled, onVerify, onError, onStateChange, onReady, onLoad, onEvent, ...props }, ref) => {
45
59
  const widgetRef = (0, react_1.useRef)(null);
46
60
  const containerRef = (0, react_1.useRef)(null);
47
61
  const [isLoading, setIsLoading] = (0, react_1.useState)(true);
62
+ const callbacksRef = (0, react_1.useRef)({
63
+ onVerify,
64
+ onError,
65
+ onStateChange,
66
+ onReady,
67
+ onLoad,
68
+ onEvent,
69
+ });
70
+ const hasStateEventRef = (0, react_1.useRef)(false);
71
+ const hasReadyRef = (0, react_1.useRef)(false);
48
72
  (0, react_1.useImperativeHandle)(ref, () => ({
49
73
  reset: () => widgetRef.current?.reset(),
50
74
  getState: () => widgetRef.current?.getState() ?? '',
@@ -58,66 +82,93 @@ exports.RibauntWidget = (0, react_1.forwardRef)(({ challengeEndpoint, verifyEndp
58
82
  .catch(console.error);
59
83
  }, []);
60
84
  (0, react_1.useEffect)(() => {
61
- const widget = widgetRef.current;
62
- if (!widget || isLoading)
85
+ callbacksRef.current = {
86
+ onVerify,
87
+ onError,
88
+ onStateChange,
89
+ onReady,
90
+ onLoad,
91
+ onEvent,
92
+ };
93
+ }, [onVerify, onError, onStateChange, onReady, onLoad, onEvent]);
94
+ (0, react_1.useEffect)(() => {
95
+ if (isLoading || !containerRef.current || widgetRef.current)
63
96
  return;
97
+ const widget = document.createElement('ribaunt-widget');
64
98
  const handleVerify = (e) => {
65
- if (onVerify) {
66
- const customEvent = e;
67
- onVerify(customEvent.detail);
68
- }
99
+ const customEvent = e;
100
+ callbacksRef.current.onVerify?.(customEvent.detail);
101
+ callbacksRef.current.onEvent?.('verify', customEvent.detail);
69
102
  };
70
103
  const handleError = (e) => {
71
- if (onError) {
72
- const customEvent = e;
73
- onError(customEvent.detail);
74
- }
104
+ const customEvent = e;
105
+ callbacksRef.current.onError?.(customEvent.detail);
106
+ callbacksRef.current.onEvent?.('error', customEvent.detail);
75
107
  };
76
108
  const handleStateChange = (e) => {
77
- if (onStateChange) {
78
- const customEvent = e;
79
- onStateChange(customEvent.detail);
80
- }
109
+ hasStateEventRef.current = true;
110
+ const customEvent = e;
111
+ callbacksRef.current.onStateChange?.(customEvent.detail);
112
+ callbacksRef.current.onEvent?.('state-change', customEvent.detail);
81
113
  };
82
114
  widget.addEventListener('verify', handleVerify);
83
115
  widget.addEventListener('error', handleError);
84
116
  widget.addEventListener('state-change', handleStateChange);
117
+ // Apply any remaining standard HTML attributes to the element
118
+ Object.entries(props).forEach(([key, value]) => {
119
+ if (value !== undefined) {
120
+ // Check if it's a valid property of the HTML element, if so set it
121
+ if (key in widget) {
122
+ widget[key] = value;
123
+ }
124
+ else {
125
+ widget.setAttribute(key, String(value));
126
+ }
127
+ }
128
+ });
129
+ syncWidgetProps(widget, {
130
+ challengeEndpoint,
131
+ verifyEndpoint,
132
+ showWarning,
133
+ warningMessage,
134
+ disabled,
135
+ });
136
+ containerRef.current.appendChild(widget);
137
+ widgetRef.current = widget;
138
+ const currentState = widget.getState?.() ?? 'initial';
139
+ if (!hasReadyRef.current) {
140
+ hasReadyRef.current = true;
141
+ callbacksRef.current.onReady?.({ state: currentState });
142
+ callbacksRef.current.onLoad?.({ state: currentState });
143
+ callbacksRef.current.onEvent?.('ready', { state: currentState });
144
+ }
145
+ const fallbackTimer = setTimeout(() => {
146
+ if (!hasStateEventRef.current) {
147
+ hasStateEventRef.current = true;
148
+ callbacksRef.current.onStateChange?.({ state: currentState });
149
+ callbacksRef.current.onEvent?.('state-change', { state: currentState });
150
+ }
151
+ }, 0);
85
152
  return () => {
153
+ clearTimeout(fallbackTimer);
86
154
  widget.removeEventListener('verify', handleVerify);
87
155
  widget.removeEventListener('error', handleError);
88
156
  widget.removeEventListener('state-change', handleStateChange);
157
+ widget.remove();
158
+ widgetRef.current = null;
89
159
  };
90
- }, [isLoading, onVerify, onError, onStateChange]);
160
+ }, [isLoading]);
91
161
  (0, react_1.useEffect)(() => {
92
- if (!isLoading && containerRef.current && !widgetRef.current) {
93
- const widget = document.createElement('ribaunt-widget');
94
- // Map camelCase props to kebab-case attributes
95
- if (challengeEndpoint)
96
- widget.setAttribute('challenge-endpoint', challengeEndpoint);
97
- if (verifyEndpoint)
98
- widget.setAttribute('verify-endpoint', verifyEndpoint);
99
- if (showWarning !== undefined)
100
- widget.setAttribute('show-warning', String(showWarning));
101
- if (warningMessage)
102
- widget.setAttribute('warning-message', warningMessage);
103
- if (disabled !== undefined)
104
- widget.setAttribute('disabled', String(disabled));
105
- // Apply any remaining standard HTML attributes to the element
106
- Object.entries(props).forEach(([key, value]) => {
107
- if (value !== undefined) {
108
- // Check if it's a valid property of the HTML element, if so set it
109
- if (key in widget) {
110
- widget[key] = value;
111
- }
112
- else {
113
- widget.setAttribute(key, String(value));
114
- }
115
- }
116
- });
117
- containerRef.current.appendChild(widget);
118
- widgetRef.current = widget;
119
- }
120
- }, [isLoading, challengeEndpoint, verifyEndpoint, showWarning, warningMessage, disabled, props]);
162
+ if (!widgetRef.current)
163
+ return;
164
+ syncWidgetProps(widgetRef.current, {
165
+ challengeEndpoint,
166
+ verifyEndpoint,
167
+ showWarning,
168
+ warningMessage,
169
+ disabled,
170
+ });
171
+ }, [challengeEndpoint, verifyEndpoint, showWarning, warningMessage, disabled]);
121
172
  return isLoading ? null : (0, jsx_runtime_1.jsx)("div", { ref: containerRef });
122
173
  });
123
174
  exports.RibauntWidget.displayName = 'RibauntWidget';