ox 1.7.0 → 1.7.1
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/CHANGELOG.md +6 -0
- package/dist/core/Siwe.d.ts.map +1 -1
- package/dist/core/Siwe.js +45 -6
- package/dist/core/Siwe.js.map +1 -1
- package/package.json +1 -1
- package/src/core/Siwe.ts +45 -5
- package/src/core/_test/Siwe.test.ts +98 -0
- package/src/version.ts +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,11 @@
|
|
|
1
1
|
# ox
|
|
2
2
|
|
|
3
|
+
## 1.7.1
|
|
4
|
+
|
|
5
|
+
### Patch Changes
|
|
6
|
+
|
|
7
|
+
- [#398](https://github.com/wevm/ox/pull/398) [`a63116b`](https://github.com/wevm/ox/commit/a63116ba88ecc8e2378e8770d21a6111574e4028) Thanks [@tmm](https://github.com/tmm)! - Rejected invalid RFC 3339 SIWE lifetime fields and invalid validation times.
|
|
8
|
+
|
|
3
9
|
## 1.7.0
|
|
4
10
|
|
|
5
11
|
### Minor Changes
|
package/dist/core/Siwe.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Siwe.d.ts","sourceRoot":"","sources":["../../src/core/Siwe.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,OAAO,MAAM,cAAc,CAAA;AACvC,OAAO,KAAK,MAAM,MAAM,aAAa,CAAA;AAErC,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,qBAAqB,CAAA;AAEvD,eAAO,MAAM,WAAW,QACwD,CAAA;AAEhF,eAAO,MAAM,OAAO,QAC8J,CAAA;AAElL,eAAO,MAAM,cAAc,QAA8B,CAAA;AAEzD,eAAO,MAAM,UAAU,QAAsB,CAAA;AAE7C,eAAO,MAAM,WAAW,QAAgC,CAAA;AAGxD,eAAO,MAAM,WAAW,QACoL,CAAA;AAG5M,eAAO,MAAM,WAAW,QACiP,CAAA;
|
|
1
|
+
{"version":3,"file":"Siwe.d.ts","sourceRoot":"","sources":["../../src/core/Siwe.ts"],"names":[],"mappings":"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"}
|
package/dist/core/Siwe.js
CHANGED
|
@@ -10,6 +10,33 @@ export const schemeRegex = /^([a-zA-Z][a-zA-Z0-9+-.]*)$/;
|
|
|
10
10
|
export const prefixRegex = /^(?:(?<scheme>[a-zA-Z][a-zA-Z0-9+-.]*):\/\/)?(?<domain>[a-zA-Z0-9+-.]*(?::[0-9]{1,5})?) (?:wants you to sign in with your Ethereum account:\n)(?<address>0x[a-fA-F0-9]{40})\n\n(?:(?<statement>.*)\n\n)?/;
|
|
11
11
|
// https://regexr.com/80gf9
|
|
12
12
|
export const suffixRegex = /(?:URI: (?<uri>.+))\n(?:Version: (?<version>.+))\n(?:Chain ID: (?<chainId>\d+))\n(?:Nonce: (?<nonce>[a-zA-Z0-9]+))\n(?:Issued At: (?<issuedAt>.+))(?:\nExpiration Time: (?<expirationTime>.+))?(?:\nNot Before: (?<notBefore>.+))?(?:\nRequest ID: (?<requestId>.+))?/;
|
|
13
|
+
const siweDateTimeRegex = /^(\d{4})-(0[1-9]|1[0-2])-(0[1-9]|[12]\d|3[01])[Tt]([01]\d|2[0-3]):[0-5]\d:[0-5]\d(?:\.\d+)?(?:[Zz]|[+-](?:[01]\d|2[0-3]):[0-5]\d)$/;
|
|
14
|
+
function parseSiweDateTime(value) {
|
|
15
|
+
const match = value.match(siweDateTimeRegex);
|
|
16
|
+
if (!match)
|
|
17
|
+
return new Date(Number.NaN);
|
|
18
|
+
const year = Number(match[1]);
|
|
19
|
+
const month = Number(match[2]);
|
|
20
|
+
const day = Number(match[3]);
|
|
21
|
+
const days = [
|
|
22
|
+
31,
|
|
23
|
+
year % 4 === 0 && (year % 100 !== 0 || year % 400 === 0) ? 29 : 28,
|
|
24
|
+
31,
|
|
25
|
+
30,
|
|
26
|
+
31,
|
|
27
|
+
30,
|
|
28
|
+
31,
|
|
29
|
+
31,
|
|
30
|
+
30,
|
|
31
|
+
31,
|
|
32
|
+
30,
|
|
33
|
+
31,
|
|
34
|
+
];
|
|
35
|
+
const daysInMonth = days[month - 1];
|
|
36
|
+
if (!daysInMonth || day > daysInMonth)
|
|
37
|
+
return new Date(Number.NaN);
|
|
38
|
+
return new Date(value.toUpperCase());
|
|
39
|
+
}
|
|
13
40
|
/**
|
|
14
41
|
* Creates [EIP-4361](https://eips.ethereum.org/EIPS/eip-4361) formatted message.
|
|
15
42
|
*
|
|
@@ -275,9 +302,11 @@ export function parseMessage(message) {
|
|
|
275
302
|
...prefix,
|
|
276
303
|
...suffix,
|
|
277
304
|
...(chainId ? { chainId: Number(chainId) } : {}),
|
|
278
|
-
...(expirationTime
|
|
279
|
-
|
|
280
|
-
|
|
305
|
+
...(expirationTime
|
|
306
|
+
? { expirationTime: parseSiweDateTime(expirationTime) }
|
|
307
|
+
: {}),
|
|
308
|
+
...(issuedAt ? { issuedAt: parseSiweDateTime(issuedAt) } : {}),
|
|
309
|
+
...(notBefore ? { notBefore: parseSiweDateTime(notBefore) } : {}),
|
|
281
310
|
...(requestId ? { requestId } : {}),
|
|
282
311
|
...(resources ? { resources } : {}),
|
|
283
312
|
...(scheme ? { scheme } : {}),
|
|
@@ -318,10 +347,20 @@ export function validateMessage(value) {
|
|
|
318
347
|
return false;
|
|
319
348
|
if (scheme && message.scheme !== scheme)
|
|
320
349
|
return false;
|
|
321
|
-
if (
|
|
322
|
-
return false;
|
|
323
|
-
if (message.notBefore && time < message.notBefore)
|
|
350
|
+
if (Number.isNaN(time.getTime()))
|
|
324
351
|
return false;
|
|
352
|
+
if (message.expirationTime) {
|
|
353
|
+
if (Number.isNaN(message.expirationTime.getTime()))
|
|
354
|
+
return false;
|
|
355
|
+
if (time >= message.expirationTime)
|
|
356
|
+
return false;
|
|
357
|
+
}
|
|
358
|
+
if (message.notBefore) {
|
|
359
|
+
if (Number.isNaN(message.notBefore.getTime()))
|
|
360
|
+
return false;
|
|
361
|
+
if (time < message.notBefore)
|
|
362
|
+
return false;
|
|
363
|
+
}
|
|
325
364
|
try {
|
|
326
365
|
if (!message.address)
|
|
327
366
|
return false;
|
package/dist/core/Siwe.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Siwe.js","sourceRoot":"","sources":["../../src/core/Siwe.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,OAAO,MAAM,cAAc,CAAA;AACvC,OAAO,KAAK,MAAM,MAAM,aAAa,CAAA;AACrC,OAAO,KAAK,GAAG,MAAM,UAAU,CAAA;AAG/B,MAAM,CAAC,MAAM,WAAW,GACtB,8EAA8E,CAAA;AAEhF,MAAM,CAAC,MAAM,OAAO,GAClB,gLAAgL,CAAA;AAElL,MAAM,CAAC,MAAM,cAAc,GAAG,2BAA2B,CAAA;AAEzD,MAAM,CAAC,MAAM,UAAU,GAAG,mBAAmB,CAAA;AAE7C,MAAM,CAAC,MAAM,WAAW,GAAG,6BAA6B,CAAA;AAExD,2BAA2B;AAC3B,MAAM,CAAC,MAAM,WAAW,GACtB,0MAA0M,CAAA;AAE5M,2BAA2B;AAC3B,MAAM,CAAC,MAAM,WAAW,GACtB,uQAAuQ,CAAA;
|
|
1
|
+
{"version":3,"file":"Siwe.js","sourceRoot":"","sources":["../../src/core/Siwe.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
package/src/core/Siwe.ts
CHANGED
|
@@ -23,6 +23,36 @@ export const prefixRegex =
|
|
|
23
23
|
export const suffixRegex =
|
|
24
24
|
/(?:URI: (?<uri>.+))\n(?:Version: (?<version>.+))\n(?:Chain ID: (?<chainId>\d+))\n(?:Nonce: (?<nonce>[a-zA-Z0-9]+))\n(?:Issued At: (?<issuedAt>.+))(?:\nExpiration Time: (?<expirationTime>.+))?(?:\nNot Before: (?<notBefore>.+))?(?:\nRequest ID: (?<requestId>.+))?/
|
|
25
25
|
|
|
26
|
+
const siweDateTimeRegex =
|
|
27
|
+
/^(\d{4})-(0[1-9]|1[0-2])-(0[1-9]|[12]\d|3[01])[Tt]([01]\d|2[0-3]):[0-5]\d:[0-5]\d(?:\.\d+)?(?:[Zz]|[+-](?:[01]\d|2[0-3]):[0-5]\d)$/
|
|
28
|
+
|
|
29
|
+
function parseSiweDateTime(value: string): Date {
|
|
30
|
+
const match = value.match(siweDateTimeRegex)
|
|
31
|
+
if (!match) return new Date(Number.NaN)
|
|
32
|
+
|
|
33
|
+
const year = Number(match[1])
|
|
34
|
+
const month = Number(match[2])
|
|
35
|
+
const day = Number(match[3])
|
|
36
|
+
const days = [
|
|
37
|
+
31,
|
|
38
|
+
year % 4 === 0 && (year % 100 !== 0 || year % 400 === 0) ? 29 : 28,
|
|
39
|
+
31,
|
|
40
|
+
30,
|
|
41
|
+
31,
|
|
42
|
+
30,
|
|
43
|
+
31,
|
|
44
|
+
31,
|
|
45
|
+
30,
|
|
46
|
+
31,
|
|
47
|
+
30,
|
|
48
|
+
31,
|
|
49
|
+
]
|
|
50
|
+
const daysInMonth = days[month - 1]
|
|
51
|
+
if (!daysInMonth || day > daysInMonth) return new Date(Number.NaN)
|
|
52
|
+
|
|
53
|
+
return new Date(value.toUpperCase())
|
|
54
|
+
}
|
|
55
|
+
|
|
26
56
|
/** [EIP-4361](https://eips.ethereum.org/EIPS/eip-4361) message fields. */
|
|
27
57
|
export type Message = {
|
|
28
58
|
/**
|
|
@@ -388,9 +418,11 @@ export function parseMessage(message: string): ExactPartial<Message> {
|
|
|
388
418
|
...prefix,
|
|
389
419
|
...suffix,
|
|
390
420
|
...(chainId ? { chainId: Number(chainId) } : {}),
|
|
391
|
-
...(expirationTime
|
|
392
|
-
|
|
393
|
-
|
|
421
|
+
...(expirationTime
|
|
422
|
+
? { expirationTime: parseSiweDateTime(expirationTime) }
|
|
423
|
+
: {}),
|
|
424
|
+
...(issuedAt ? { issuedAt: parseSiweDateTime(issuedAt) } : {}),
|
|
425
|
+
...(notBefore ? { notBefore: parseSiweDateTime(notBefore) } : {}),
|
|
394
426
|
...(requestId ? { requestId } : {}),
|
|
395
427
|
...(resources ? { resources } : {}),
|
|
396
428
|
...(scheme ? { scheme } : {}),
|
|
@@ -431,8 +463,16 @@ export function validateMessage(value: validateMessage.Value): boolean {
|
|
|
431
463
|
if (nonce && message.nonce !== nonce) return false
|
|
432
464
|
if (scheme && message.scheme !== scheme) return false
|
|
433
465
|
|
|
434
|
-
if (
|
|
435
|
-
|
|
466
|
+
if (Number.isNaN(time.getTime())) return false
|
|
467
|
+
|
|
468
|
+
if (message.expirationTime) {
|
|
469
|
+
if (Number.isNaN(message.expirationTime.getTime())) return false
|
|
470
|
+
if (time >= message.expirationTime) return false
|
|
471
|
+
}
|
|
472
|
+
if (message.notBefore) {
|
|
473
|
+
if (Number.isNaN(message.notBefore.getTime())) return false
|
|
474
|
+
if (time < message.notBefore) return false
|
|
475
|
+
}
|
|
436
476
|
|
|
437
477
|
try {
|
|
438
478
|
if (!message.address) return false
|
|
@@ -546,6 +546,81 @@ Expiration Time: 2022-02-04T00:00:00.000Z`
|
|
|
546
546
|
)
|
|
547
547
|
})
|
|
548
548
|
|
|
549
|
+
test.each([
|
|
550
|
+
['never', '2023-02-01T00:00:00Z'],
|
|
551
|
+
['2023-02-29T00:00:00Z', '2023-02-28T12:00:00Z'],
|
|
552
|
+
['2023-04-31T00:00:00Z', '2023-04-30T12:00:00Z'],
|
|
553
|
+
['2023-02-01T24:00:00Z', '2023-02-01T12:00:00Z'],
|
|
554
|
+
])(
|
|
555
|
+
'behavior: invalid RFC 3339 expirationTime `%s`',
|
|
556
|
+
(expirationTime, time) => {
|
|
557
|
+
const message = `https://example.com wants you to sign in with your Ethereum account:
|
|
558
|
+
0xA0Cf798816D4b9b9866b5330EEa46a18382f251e
|
|
559
|
+
|
|
560
|
+
URI: https://example.com/path
|
|
561
|
+
Version: 1
|
|
562
|
+
Chain ID: 1
|
|
563
|
+
Nonce: foobarbaz
|
|
564
|
+
Issued At: 2023-02-01T00:00:00.000Z
|
|
565
|
+
Expiration Time: ${expirationTime}`
|
|
566
|
+
const parsed = Siwe.parseMessage(message)
|
|
567
|
+
expect({
|
|
568
|
+
invalid: Number.isNaN(parsed.expirationTime?.getTime()),
|
|
569
|
+
valid: Siwe.validateMessage({
|
|
570
|
+
message: parsed,
|
|
571
|
+
time: new Date(time),
|
|
572
|
+
}),
|
|
573
|
+
}).toMatchInlineSnapshot(`
|
|
574
|
+
{
|
|
575
|
+
"invalid": true,
|
|
576
|
+
"valid": false,
|
|
577
|
+
}
|
|
578
|
+
`)
|
|
579
|
+
},
|
|
580
|
+
)
|
|
581
|
+
|
|
582
|
+
test.each([
|
|
583
|
+
'2030-02-04t00:00:00Z',
|
|
584
|
+
'2030-02-04T00:00:00z',
|
|
585
|
+
'2030-02-04t00:00:00z',
|
|
586
|
+
])('behavior: lowercase RFC 3339 expirationTime `%s`', (expirationTime) => {
|
|
587
|
+
const message = `https://example.com wants you to sign in with your Ethereum account:
|
|
588
|
+
0xA0Cf798816D4b9b9866b5330EEa46a18382f251e
|
|
589
|
+
|
|
590
|
+
URI: https://example.com/path
|
|
591
|
+
Version: 1
|
|
592
|
+
Chain ID: 1
|
|
593
|
+
Nonce: foobarbaz
|
|
594
|
+
Issued At: 2023-02-01T00:00:00.000Z
|
|
595
|
+
Expiration Time: ${expirationTime}`
|
|
596
|
+
const parsed = Siwe.parseMessage(message)
|
|
597
|
+
expect(parsed.expirationTime).toMatchInlineSnapshot(
|
|
598
|
+
'2030-02-04T00:00:00.000Z',
|
|
599
|
+
)
|
|
600
|
+
expect(
|
|
601
|
+
Siwe.validateMessage({
|
|
602
|
+
message: parsed,
|
|
603
|
+
time: new Date('2029-02-04T00:00:00Z'),
|
|
604
|
+
}),
|
|
605
|
+
).toBeTruthy()
|
|
606
|
+
})
|
|
607
|
+
|
|
608
|
+
test('behavior: leap-year expirationTime', () => {
|
|
609
|
+
const message = `https://example.com wants you to sign in with your Ethereum account:
|
|
610
|
+
0xA0Cf798816D4b9b9866b5330EEa46a18382f251e
|
|
611
|
+
|
|
612
|
+
URI: https://example.com/path
|
|
613
|
+
Version: 1
|
|
614
|
+
Chain ID: 1
|
|
615
|
+
Nonce: foobarbaz
|
|
616
|
+
Issued At: 2023-02-01T00:00:00.000Z
|
|
617
|
+
Expiration Time: 2032-02-29T00:00:00Z`
|
|
618
|
+
const parsed = Siwe.parseMessage(message)
|
|
619
|
+
expect(parsed.expirationTime).toMatchInlineSnapshot(
|
|
620
|
+
'2032-02-29T00:00:00.000Z',
|
|
621
|
+
)
|
|
622
|
+
})
|
|
623
|
+
|
|
549
624
|
test('behavior: with notBefore', () => {
|
|
550
625
|
const message = `https://example.com wants you to sign in with your Ethereum account:
|
|
551
626
|
0xA0Cf798816D4b9b9866b5330EEa46a18382f251e
|
|
@@ -730,6 +805,29 @@ describe('validateMessage', () => {
|
|
|
730
805
|
).toBeFalsy()
|
|
731
806
|
})
|
|
732
807
|
|
|
808
|
+
test.each(['expirationTime', 'notBefore'] as const)(
|
|
809
|
+
'behavior: invalid %s',
|
|
810
|
+
(field) => {
|
|
811
|
+
expect(
|
|
812
|
+
Siwe.validateMessage({
|
|
813
|
+
message: {
|
|
814
|
+
...message,
|
|
815
|
+
[field]: new Date('never'),
|
|
816
|
+
},
|
|
817
|
+
}),
|
|
818
|
+
).toBeFalsy()
|
|
819
|
+
},
|
|
820
|
+
)
|
|
821
|
+
|
|
822
|
+
test('behavior: invalid time', () => {
|
|
823
|
+
expect(
|
|
824
|
+
Siwe.validateMessage({
|
|
825
|
+
message,
|
|
826
|
+
time: new Date('never'),
|
|
827
|
+
}),
|
|
828
|
+
).toBeFalsy()
|
|
829
|
+
})
|
|
830
|
+
|
|
733
831
|
test('behavior: time is before notBefore', () => {
|
|
734
832
|
vi.useFakeTimers()
|
|
735
833
|
vi.setSystemTime(new Date(Date.UTC(2023, 1, 1)))
|
package/src/version.ts
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
1
|
/** @internal */
|
|
2
|
-
export const version = '1.7.
|
|
2
|
+
export const version = '1.7.1'
|