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.
- package/dist/cjs/index.cjs +32 -7
- package/dist/cjs/index.d.ts +31 -0
- package/dist/cjs/index.d.ts.map +1 -1
- package/dist/cjs/index.js +200 -0
- package/dist/cjs/index.js.map +1 -1
- package/dist/cjs/package.json +3 -0
- package/dist/cjs/solver.d.ts.map +1 -1
- package/dist/cjs/solver.js +24 -21
- package/dist/cjs/solver.js.map +1 -1
- package/dist/cjs/widget-react.d.ts +8 -1
- package/dist/cjs/widget-react.d.ts.map +1 -1
- package/dist/cjs/widget-react.js +96 -45
- package/dist/cjs/widget-react.js.map +1 -1
- package/dist/cjs/widget.d.ts +4 -0
- package/dist/cjs/widget.d.ts.map +1 -1
- package/dist/cjs/widget.js +44 -16
- package/dist/cjs/widget.js.map +1 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +32 -7
- package/dist/index.js.map +1 -1
- package/dist/solver.d.ts.map +1 -1
- package/dist/solver.js +24 -21
- package/dist/solver.js.map +1 -1
- package/dist/widget-react.d.ts +8 -1
- package/dist/widget-react.d.ts.map +1 -1
- package/dist/widget-react.js +96 -45
- package/dist/widget-react.js.map +1 -1
- package/dist/widget.d.ts +4 -0
- package/dist/widget.d.ts.map +1 -1
- package/dist/widget.js +44 -16
- package/dist/widget.js.map +1 -1
- package/package.json +7 -4
- package/scripts/prepare-cjs.mjs +11 -0
package/dist/cjs/index.cjs
CHANGED
|
@@ -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,
|
|
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
|
|
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,
|
|
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
|
package/dist/cjs/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"
|
|
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
|
package/dist/cjs/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":";;;;;
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":";;;;;AA+FA,0CAcC;AA4DD,wCAoBC;AASD,wCAwDC;AA9PD,oDAA4B;AAC5B,gEAA+B;AAe/B,SAAS,iBAAiB,CAAC,MAAM,GAAG,CAAC;IACnC,MAAM,MAAM,GAAG,gBAAM,CAAC,WAAW,CAAC,MAAM,CAAC,CAAC;IAC1C,OAAO,MAAM,CAAC,QAAQ,CAAC,QAAQ,CAAC,CAAC,KAAK,CAAC,CAAC,EAAE,MAAM,CAAC,CAAC;AACpD,CAAC;AAED,SAAS,sBAAsB,CAAC,UAAkB,EAAE,UAAkB;IACpE,OAAO;QACL,SAAS,EAAE,iBAAiB,EAAE;QAC9B,UAAU;QACV,OAAO,EAAE,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,GAAG,EAAE,GAAG,IAAI,CAAC,GAAG,UAAU;KACpD,CAAC;AACJ,CAAC;AAED,SAAS,SAAS;IAChB,MAAM,MAAM,GAAG,OAAO,CAAC,GAAG,CAAC,cAAc,CAAC;IAE1C,IAAI,CAAC,MAAM,EAAE,CAAC;QACZ,MAAM,IAAI,KAAK,CAAC,iDAAiD,CAAC,CAAC;IACrE,CAAC;IAED,OAAO,MAAM,CAAC;AAChB,CAAC;AAED,SAAS,aAAa,CAAC,OAA8B;IACnD,OAAO,sBAAG,CAAC,IAAI,CAAC,OAAO,EAAE,SAAS,EAAE,CAAC,CAAC;AACxC,CAAC;AAED,SAAS,iBAAiB,CAAC,MAAc;IACvC,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,MAAM,CAAC,EAAE,CAAC;QAC7B,MAAM,IAAI,KAAK,CAAC,0CAA0C,CAAC,CAAC;IAC9D,CAAC;IAED,MAAM,UAAU,GAAG,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC;IACtC,IAAI,UAAU,GAAG,CAAC,EAAE,CAAC;QACnB,MAAM,IAAI,KAAK,CAAC,qCAAqC,CAAC,CAAC;IACzD,CAAC;IAED,OAAO,UAAU,CAAC;AACpB,CAAC;AAED,SAAS,qBAAqB,CAAC,UAAkB;IAC/C,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,UAAU,CAAC,EAAE,CAAC;QACjC,MAAM,IAAI,KAAK,CAAC,8CAA8C,CAAC,CAAC;IAClE,CAAC;IAED,MAAM,UAAU,GAAG,IAAI,CAAC,KAAK,CAAC,UAAU,CAAC,CAAC;IAC1C,IAAI,UAAU,GAAG,CAAC,EAAE,CAAC;QACnB,MAAM,IAAI,KAAK,CAAC,yCAAyC,CAAC,CAAC;IAC7D,CAAC;IAED,OAAO,UAAU,CAAC;AACpB,CAAC;AAED,SAAS,cAAc,CAAC,UAAkB;IACxC,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,UAAU,CAAC,EAAE,CAAC;QACjC,MAAM,IAAI,KAAK,CAAC,uCAAuC,CAAC,CAAC;IAC3D,CAAC;IAED,MAAM,UAAU,GAAG,IAAI,CAAC,KAAK,CAAC,UAAU,CAAC,CAAC;IAC1C,IAAI,UAAU,GAAG,CAAC,EAAE,CAAC;QACnB,MAAM,IAAI,KAAK,CAAC,yCAAyC,CAAC,CAAC;IAC7D,CAAC;IAED,OAAO,UAAU,CAAC;AACpB,CAAC;AAED,SAAS,qBAAqB,CAAC,UAAkB,EAAE,UAAkB;IACnE,MAAM,OAAO,GAAG,sBAAsB,CAAC,UAAU,EAAE,UAAU,CAAC,CAAC;IAC/D,OAAO,aAAa,CAAC,OAAO,CAAC,CAAC;AAChC,CAAC;AAED;;;;;;;GAOG;AACH,SAAgB,eAAe,CAC7B,aAAqB,CAAC,EACtB,SAAiB,CAAC,EAClB,aAAqB,EAAE;IAEvB,MAAM,oBAAoB,GAAG,qBAAqB,CAAC,UAAU,CAAC,CAAC;IAC/D,MAAM,gBAAgB,GAAG,iBAAiB,CAAC,MAAM,CAAC,CAAC;IACnD,MAAM,aAAa,GAAG,cAAc,CAAC,UAAU,CAAC,CAAC;IAEjD,MAAM,UAAU,GAAG,KAAK,CAAC,IAAI,CAC3B,EAAE,MAAM,EAAE,gBAAgB,EAAE,EAC5B,GAAG,EAAE,CAAC,qBAAqB,CAAC,oBAAoB,EAAE,aAAa,CAAC,CACjE,CAAC;IACF,OAAO,UAAU,CAAC;AACpB,CAAC;AAED,SAAS,oBAAoB,CAAC,KAAqB;IACjD,IAAI,CAAC;QACH,MAAM,OAAO,GAAG,sBAAG,CAAC,MAAM,CAAC,KAAK,CAAiC,CAAC;QAClE,IAAI,CAAC,OAAO;YAAE,OAAO,SAAS,CAAC;QAE/B,MAAM,EAAE,SAAS,EAAE,UAAU,EAAE,GAAG,OAAO,CAAC;QAC1C,MAAM,MAAM,GAAG,GAAG,CAAC,MAAM,CAAC,UAAU,CAAC,CAAC;QAEtC,IAAI,KAAK,GAAG,CAAC,CAAC;QACd,OAAO,IAAI,EAAE,CAAC;YACZ,MAAM,IAAI,GAAG,gBAAM;iBAChB,UAAU,CAAC,QAAQ,CAAC;iBACpB,MAAM,CAAC,GAAG,SAAS,GAAG,KAAK,EAAE,CAAC;iBAC9B,MAAM,CAAC,KAAK,CAAC,CAAC;YAEjB,IAAI,IAAI,CAAC,UAAU,CAAC,MAAM,CAAC,EAAE,CAAC;gBAC5B,OAAO,EAAE,KAAK,EAAE,MAAM,CAAC,KAAK,CAAC,EAAE,IAAI,EAAE,CAAC;YACxC,CAAC;YAED,KAAK,EAAE,CAAC;QACV,CAAC;IACH,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACb,OAAO,SAAS,CAAC;IACnB,CAAC;AACH,CAAC;AAED,SAAS,oBAAoB,CAAC,KAAqB,EAAE,KAAkC;IACrF,IAAI,KAAK,KAAK,SAAS,IAAI,KAAK,KAAK,IAAI,EAAE,CAAC;QAC1C,OAAO,KAAK,CAAC;IACf,CAAC;IAED,IAAI,CAAC;QACH,MAAM,OAAO,GAAG,sBAAG,CAAC,MAAM,CAAC,KAAK,EAAE,SAAS,EAAE,CAA0B,CAAC;QAExE,MAAM,GAAG,GAAG,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,GAAG,EAAE,GAAG,IAAI,CAAC,CAAC;QAC1C,IAAI,OAAO,CAAC,OAAO,GAAG,GAAG;YAAE,OAAO,KAAK,CAAC;QAExC,MAAM,UAAU,GAAG,OAAO,KAAK,KAAK,QAAQ,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC;QACrE,MAAM,IAAI,GAAG,gBAAM;aAChB,UAAU,CAAC,QAAQ,CAAC;aACpB,MAAM,CAAC,GAAG,OAAO,CAAC,SAAS,GAAG,UAAU,EAAE,CAAC;aAC3C,MAAM,CAAC,KAAK,CAAC,CAAC;QAEjB,MAAM,MAAM,GAAG,GAAG,CAAC,MAAM,CAAC,OAAO,CAAC,UAAU,CAAC,CAAC;QAC9C,OAAO,IAAI,CAAC,UAAU,CAAC,MAAM,CAAC,CAAC;IACjC,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACb,OAAO,KAAK,CAAC;IACf,CAAC;AACH,CAAC;AAUD,SAAgB,cAAc,CAC5B,KAAwC;IAExC,IAAI,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,EAAE,CAAC;QACzB,MAAM,SAAS,GAAwB,EAAE,CAAC;QAE1C,KAAK,MAAM,WAAW,IAAI,KAAK,EAAE,CAAC;YAChC,MAAM,QAAQ,GAAG,oBAAoB,CAAC,WAAW,CAAC,CAAC;YACnD,IAAI,CAAC,QAAQ,EAAE,CAAC;gBACd,OAAO,SAAS,CAAC;YACnB,CAAC;YAED,SAAS,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;QAC3B,CAAC;QAED,OAAO,SAAS,CAAC;IACnB,CAAC;IAED,MAAM,QAAQ,GAAG,oBAAoB,CAAC,KAAK,CAAC,CAAC;IAC7C,OAAO,QAAQ,CAAC;AAClB,CAAC;AAED;;;;;;GAMG;AACH,SAAgB,cAAc,CAC5B,KAAwC,EACxC,KAAyF;IAEzF,IAAI,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,EAAE,CAAC;QACzB,IAAI,MAA8B,CAAC;QACnC,IAAI,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,EAAE,CAAC;YACzB,IAAI,KAAK,CAAC,MAAM,KAAK,KAAK,CAAC,MAAM,EAAE,CAAC;gBAClC,OAAO,KAAK,CAAC;YACf,CAAC;YACD,IAAI,KAAK,CAAC,MAAM,GAAG,CAAC,IAAI,OAAO,KAAK,CAAC,CAAC,CAAC,KAAK,QAAQ,IAAI,OAAO,IAAI,KAAK,CAAC,CAAC,CAAC,EAAE,CAAC;gBAC5E,MAAM,GAAI,KAA6B,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC;YAC5D,CAAC;iBAAM,CAAC;gBACN,MAAM,GAAG,KAA+B,CAAC;YAC3C,CAAC;QACH,CAAC;aAAM,CAAC;YACN,OAAO,KAAK,CAAC;QACf,CAAC;QAED,KAAK,IAAI,KAAK,GAAG,CAAC,EAAE,KAAK,GAAG,KAAK,CAAC,MAAM,EAAE,KAAK,EAAE,EAAE,CAAC;YAClD,MAAM,cAAc,GAAG,KAAK,CAAC,KAAK,CAAC,CAAC;YACpC,MAAM,UAAU,GAAG,MAAM,CAAC,KAAK,CAAC,CAAC;YAEjC,IAAI,cAAc,KAAK,SAAS,IAAI,UAAU,KAAK,SAAS,EAAE,CAAC;gBAC7D,OAAO,KAAK,CAAC;YACf,CAAC;YAED,IAAI,CAAC,oBAAoB,CAAC,cAAc,EAAE,UAAU,CAAC,EAAE,CAAC;gBACtD,OAAO,KAAK,CAAC;YACf,CAAC;QACH,CAAC;QAED,OAAO,IAAI,CAAC;IACd,CAAC;IAED,IAAI,cAA+B,CAAC;IACpC,IAAI,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,EAAE,CAAC;QACzB,IAAI,KAAK,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;YACvB,OAAO,KAAK,CAAC;QACf,CAAC;QACD,IAAI,OAAO,KAAK,CAAC,CAAC,CAAC,KAAK,QAAQ,IAAI,OAAO,IAAI,KAAK,CAAC,CAAC,CAAC,EAAE,CAAC;YACxD,cAAc,GAAI,KAAK,CAAC,CAAC,CAAuB,CAAC,KAAK,CAAC;QACzD,CAAC;aAAM,CAAC;YACN,cAAc,GAAG,KAAK,CAAC,CAAC,CAAoB,CAAC;QAC/C,CAAC;IACH,CAAC;SAAM,IAAI,OAAO,KAAK,KAAK,QAAQ,IAAI,OAAO,IAAI,KAAK,EAAE,CAAC;QACzD,cAAc,GAAI,KAA2B,CAAC,KAAK,CAAC;IACtD,CAAC;SAAM,CAAC;QACN,cAAc,GAAG,KAAwB,CAAC;IAC5C,CAAC;IAED,IAAI,cAAc,KAAK,SAAS,EAAE,CAAC;QACjC,OAAO,KAAK,CAAC;IACf,CAAC;IACD,MAAM,MAAM,GAAG,oBAAoB,CAAC,KAAK,EAAE,cAAc,CAAC,CAAC;IAC3D,OAAO,MAAM,CAAC;AAChB,CAAC"}
|
package/dist/cjs/solver.d.ts.map
CHANGED
|
@@ -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;
|
|
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"}
|
package/dist/cjs/solver.js
CHANGED
|
@@ -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
|
|
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
|
-
|
|
38
|
-
|
|
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
|
/**
|
package/dist/cjs/solver.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"solver.js","sourceRoot":"","sources":["../../src/solver.ts"],"names":[],"mappings":";AAAA;;GAEG;;
|
|
1
|
+
{"version":3,"file":"solver.js","sourceRoot":"","sources":["../../src/solver.ts"],"names":[],"mappings":";AAAA;;GAEG;;AAwDH,oDAsBC;AAKD,wCA2BC;AAjGD;;GAEG;AACH,SAAS,SAAS,CAAC,KAAa;IAC9B,IAAI,CAAC;QACH,MAAM,KAAK,GAAG,KAAK,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;QAC/B,IAAI,KAAK,CAAC,MAAM,KAAK,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC;YAAE,OAAO,IAAI,CAAC;QAEjD,MAAM,iBAAiB,GAAG,KAAK,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,IAAI,EAAE,GAAG,CAAC,CAAC,OAAO,CAAC,IAAI,EAAE,GAAG,CAAC,CAAC;QACzE,MAAM,aAAa,GAAG,iBAAiB,CAAC,MAAM,CAC5C,iBAAiB,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,iBAAiB,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,EACrE,GAAG,CACJ,CAAC;QAEF,MAAM,OAAO,GAAG,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,aAAa,CAAC,CAAC,CAAC;QAChD,OAAO,OAA2B,CAAC;IACrC,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,IAAI,CAAC;IACd,CAAC;AACH,CAAC;AAED;;GAEG;AACH,KAAK,UAAU,MAAM,CAAC,OAAe;IACnC,IAAI,OAAO,WAAW,KAAK,WAAW,EAAE,CAAC;QACvC,MAAM,IAAI,KAAK,CAAC,wDAAwD,CAAC,CAAC;IAC5E,CAAC;IAED,IAAI,CAAC,UAAU,CAAC,MAAM,EAAE,MAAM,EAAE,CAAC;QAC/B,MAAM,IAAI,KAAK,CAAC,wDAAwD,CAAC,CAAC;IAC5E,CAAC;IAED,MAAM,SAAS,GAAG,IAAI,WAAW,EAAE,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC;IACpD,MAAM,UAAU,GAAG,MAAM,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC,SAAS,EAAE,SAAS,CAAC,CAAC;IACpE,MAAM,SAAS,GAAG,KAAK,CAAC,IAAI,CAAC,IAAI,UAAU,CAAC,UAAU,CAAC,CAAC,CAAC;IACzD,MAAM,OAAO,GAAG,SAAS,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC,QAAQ,CAAC,CAAC,EAAE,GAAG,CAAC,CAAC,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;IAC7E,OAAO,OAAO,CAAC;AACjB,CAAC;AAED;;GAEG;AACI,KAAK,UAAU,oBAAoB,CAAC,KAAa;IACtD,MAAM,OAAO,GAAG,SAAS,CAAC,KAAK,CAAC,CAAC;IACjC,IAAI,CAAC,OAAO;QAAE,OAAO,SAAS,CAAC;IAE/B,MAAM,EAAE,SAAS,EAAE,UAAU,EAAE,GAAG,OAAO,CAAC;IAC1C,MAAM,MAAM,GAAG,GAAG,CAAC,MAAM,CAAC,UAAU,CAAC,CAAC;IAEtC,IAAI,KAAK,GAAG,CAAC,CAAC;IACd,OAAO,IAAI,EAAE,CAAC;QACZ,MAAM,IAAI,GAAG,MAAM,MAAM,CAAC,GAAG,SAAS,GAAG,KAAK,EAAE,CAAC,CAAC;QAElD,IAAI,IAAI,CAAC,UAAU,CAAC,MAAM,CAAC,EAAE,CAAC;YAC5B,OAAO,EAAE,KAAK,EAAE,MAAM,CAAC,KAAK,CAAC,EAAE,IAAI,EAAE,CAAC;QACxC,CAAC;QAED,KAAK,EAAE,CAAC;QAER,2DAA2D;QAC3D,IAAI,KAAK,GAAG,IAAI,KAAK,CAAC,EAAE,CAAC;YACvB,MAAM,IAAI,OAAO,CAAC,OAAO,CAAC,EAAE,CAAC,UAAU,CAAC,OAAO,EAAE,CAAC,CAAC,CAAC,CAAC;QACvD,CAAC;IACH,CAAC;AACH,CAAC;AAED;;GAEG;AACI,KAAK,UAAU,cAAc,CAClC,MAAgB,EAChB,UAAuC;IAEvC,MAAM,SAAS,GAAwB,EAAE,CAAC;IAE1C,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,MAAM,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;QACvC,MAAM,KAAK,GAAG,MAAM,CAAC,CAAC,CAAC,CAAC;QACxB,IAAI,CAAC,KAAK,EAAE,CAAC;YACX,MAAM,IAAI,KAAK,CAAC,0BAA0B,CAAC,EAAE,CAAC,CAAC;QACjD,CAAC;QAED,MAAM,QAAQ,GAAG,MAAM,oBAAoB,CAAC,KAAK,CAAC,CAAC;QACnD,IAAI,CAAC,QAAQ,EAAE,CAAC;YACd,MAAM,IAAI,KAAK,CAAC,6BAA6B,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;QACxD,CAAC;QAED,SAAS,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;QAEzB,kBAAkB;QAClB,IAAI,UAAU,EAAE,CAAC;YACf,MAAM,QAAQ,GAAG,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,GAAG,MAAM,CAAC,MAAM,CAAC,GAAG,GAAG,CAAC,CAAC;YAC7D,UAAU,CAAC,QAAQ,CAAC,CAAC;QACvB,CAAC;IACH,CAAC;IAED,OAAO,SAAS,CAAC;AACnB,CAAC"}
|
|
@@ -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;
|
|
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"}
|
package/dist/cjs/widget-react.js
CHANGED
|
@@ -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
|
-
|
|
62
|
-
|
|
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
|
-
|
|
66
|
-
|
|
67
|
-
|
|
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
|
-
|
|
72
|
-
|
|
73
|
-
|
|
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
|
-
|
|
78
|
-
|
|
79
|
-
|
|
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
|
|
160
|
+
}, [isLoading]);
|
|
91
161
|
(0, react_1.useEffect)(() => {
|
|
92
|
-
if (!
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
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';
|