Skip to content

Commit 281782d

Browse files
authored
Fix CAIP-122 verification (#193)
# Problem Various issues found when testing the CAIP-122 signature verification # Solution 1. Fixed a few SIWA references 2. Fixed the signature verification to allow for the hashed version in addition to the pure string version. 3. `publicKey` should be `Sr` not `SR` (verification doesn't care however) 4. Added additional test generated from FA code 5. Match address encoding before comparing for the CAIP-122 payload 6. Fix address extraction 7. Fix expired parsing
1 parent 87b24c6 commit 281782d

18 files changed

+132
-44
lines changed

README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,7 @@ Looking for SIWF v1 resources? [Go to the `v1` branch](https://github.com/Projec
3434

3535
## 💻 Prerequisites<a name="-prerequisites"></a>
3636

37-
Using Sign In With Access requires:
37+
Using Sign In With Frequency requires:
3838

3939
- Frequency Provider setup
4040
- Frequency Node RPC access

docs/book.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ authors = ["Project Liberty Labs"]
33
language = "en"
44
multilingual = false
55
src = "src"
6-
title = "Sign In With Access"
6+
title = "Sign In With Frequency"
77

88
[preprocessor.local]
99
command = "node preprocessor.mjs"

docs/src/DataStructures/Request.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
```json
22
{
3-
"signedRequest": "eyJyZXF1ZXN0ZWRTaWduYXR1cmVzIjp7InB1YmxpY0tleSI6eyJlbmNvZGVkVmFsdWUiOiJmNmNMNHdxMUhVTngxMVRjdmRBQk5mOVVOWFhveUg0N21WVXdUNTl0elNGUlc4eURIIiwiZW5jb2RpbmciOiJiYXNlNTgiLCJmb3JtYXQiOiJzczU4IiwidHlwZSI6IlNSMjU1MTkifSwic2lnbmF0dXJlIjp7ImFsZ28iOiJTUjI1NTE5IiwiZW5jb2RpbmciOiJiYXNlMTYiLCJlbmNvZGVkVmFsdWUiOiIweGU2NjBiZjA4MTQxNzI3OGE4YzYxOTkwZGM3N2JjZTZjOTQxZWU3ZjM0ZDMwZGRiYjVjYzdjMzk2NmE0MDhjMDA3YmU1MGYyNjBkMzc2Y2I3ZjAyYzRiOGI2ZmFjZTkzOTJkZjZhNzE4MTYzZmJmZDI2YTNkNWQwYzA4NzYwNDgwIn0sInBheWxvYWQiOnsiY2FsbGJhY2siOiJodHRwOi8vbG9jYWxob3N0OjMwMDAiLCJwZXJtaXNzaW9ucyI6WzUsNyw4LDksMTBdfX0sInJlcXVlc3RlZENyZWRlbnRpYWxzIjpbeyJ0eXBlIjoiVmVyaWZpZWRHcmFwaEtleUNyZWRlbnRpYWwiLCJoYXNoIjpbImJjaXFtZHZteGQ1NHp2ZTVraWZ5Y2dzZHRvYWhzNWVjZjRoYWwydHMzZWV4a2dvY3ljNW9jYTJ5Il19LHsiYW55T2YiOlt7InR5cGUiOiJWZXJpZmllZEVtYWlsQWRkcmVzc0NyZWRlbnRpYWwiLCJoYXNoIjpbImJjaXFlNHFvY3poZnRpY2k0ZHpmdmZiZWw3Zm80aDRzcjVncmNvM29vdnd5azZ5NHluZjQ0dHNpIl19LHsidHlwZSI6IlZlcmlmaWVkUGhvbmVOdW1iZXJDcmVkZW50aWFsIiwiaGFzaCI6WyJiY2lxanNwbmJ3cGMzd2p4NGZld2NlazVkYXlzZGpwYmY1eGppbXo1d251NXVqN2UzdnUydXducSJdfV19XX0",
3+
"signedRequest": "eyJyZXF1ZXN0ZWRTaWduYXR1cmVzIjp7InB1YmxpY0tleSI6eyJlbmNvZGVkVmFsdWUiOiJmNmNMNHdxMUhVTngxMVRjdmRBQk5mOVVOWFhveUg0N21WVXdUNTl0elNGUlc4eURIIiwiZW5jb2RpbmciOiJiYXNlNTgiLCJmb3JtYXQiOiJzczU4IiwidHlwZSI6IlNyMjU1MTkifSwic2lnbmF0dXJlIjp7ImFsZ28iOiJTUjI1NTE5IiwiZW5jb2RpbmciOiJiYXNlMTYiLCJlbmNvZGVkVmFsdWUiOiIweDNlMTdhYzM3Yzk3ZWE3M2E3YzM1ZjBjYTJkZTcxYmY3MmE5NjlkYjhiNjQyYzU3ZTI2N2Q4N2Q1OTA3ZGM4MzVmYTJjODI4MTdlODA2YTQ5NGIyY2E5Y2U5MjJmNDM1NDY4M2U4YzAxMzY5NTNlMGZlNWExODJkMzU0NjQ2Yzg4In0sInBheWxvYWQiOnsiY2FsbGJhY2siOiJodHRwOi8vbG9jYWxob3N0OjMwMDAiLCJwZXJtaXNzaW9ucyI6WzUsNyw4LDksMTBdfX0sInJlcXVlc3RlZENyZWRlbnRpYWxzIjpbeyJ0eXBlIjoiVmVyaWZpZWRHcmFwaEtleUNyZWRlbnRpYWwiLCJoYXNoIjpbImJjaXFtZHZteGQ1NHp2ZTVraWZ5Y2dzZHRvYWhzNWVjZjRoYWwydHMzZWV4a2dvY3ljNW9jYTJ5Il19LHsiYW55T2YiOlt7InR5cGUiOiJWZXJpZmllZEVtYWlsQWRkcmVzc0NyZWRlbnRpYWwiLCJoYXNoIjpbImJjaXFlNHFvY3poZnRpY2k0ZHpmdmZiZWw3Zm80aDRzcjVncmNvM29vdnd5azZ5NHluZjQ0dHNpIl19LHsidHlwZSI6IlZlcmlmaWVkUGhvbmVOdW1iZXJDcmVkZW50aWFsIiwiaGFzaCI6WyJiY2lxanNwbmJ3cGMzd2p4NGZld2NlazVkYXlzZGpwYmY1eGppbXo1d251NXVqN2UzdnUydXducSJdfV19XX0",
44
"mode": "dark"
55
}
66
```

docs/src/DataStructures/RequestUrl.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,3 @@
11
```json
2-
"https://testnet.frequencyaccess.com/siwa/start?signedRequest=eyJyZXF1ZXN0ZWRTaWduYXR1cmVzIjp7InB1YmxpY0tleSI6eyJlbmNvZGVkVmFsdWUiOiJmNmNMNHdxMUhVTngxMVRjdmRBQk5mOVVOWFhveUg0N21WVXdUNTl0elNGUlc4eURIIiwiZW5jb2RpbmciOiJiYXNlNTgiLCJmb3JtYXQiOiJzczU4IiwidHlwZSI6IlNSMjU1MTkifSwic2lnbmF0dXJlIjp7ImFsZ28iOiJTUjI1NTE5IiwiZW5jb2RpbmciOiJiYXNlMTYiLCJlbmNvZGVkVmFsdWUiOiIweGU2NjBiZjA4MTQxNzI3OGE4YzYxOTkwZGM3N2JjZTZjOTQxZWU3ZjM0ZDMwZGRiYjVjYzdjMzk2NmE0MDhjMDA3YmU1MGYyNjBkMzc2Y2I3ZjAyYzRiOGI2ZmFjZTkzOTJkZjZhNzE4MTYzZmJmZDI2YTNkNWQwYzA4NzYwNDgwIn0sInBheWxvYWQiOnsiY2FsbGJhY2siOiJodHRwOi8vbG9jYWxob3N0OjMwMDAiLCJwZXJtaXNzaW9ucyI6WzUsNyw4LDksMTBdfX0sInJlcXVlc3RlZENyZWRlbnRpYWxzIjpbeyJ0eXBlIjoiVmVyaWZpZWRHcmFwaEtleUNyZWRlbnRpYWwiLCJoYXNoIjpbImJjaXFtZHZteGQ1NHp2ZTVraWZ5Y2dzZHRvYWhzNWVjZjRoYWwydHMzZWV4a2dvY3ljNW9jYTJ5Il19LHsiYW55T2YiOlt7InR5cGUiOiJWZXJpZmllZEVtYWlsQWRkcmVzc0NyZWRlbnRpYWwiLCJoYXNoIjpbImJjaXFlNHFvY3poZnRpY2k0ZHpmdmZiZWw3Zm80aDRzcjVncmNvM29vdnd5azZ5NHluZjQ0dHNpIl19LHsidHlwZSI6IlZlcmlmaWVkUGhvbmVOdW1iZXJDcmVkZW50aWFsIiwiaGFzaCI6WyJiY2lxanNwbmJ3cGMzd2p4NGZld2NlazVkYXlzZGpwYmY1eGppbXo1d251NXVqN2UzdnUydXducSJdfV19XX0&mode=dark"
2+
"https://testnet.frequencyaccess.com/siwa/start?signedRequest=eyJyZXF1ZXN0ZWRTaWduYXR1cmVzIjp7InB1YmxpY0tleSI6eyJlbmNvZGVkVmFsdWUiOiJmNmNMNHdxMUhVTngxMVRjdmRBQk5mOVVOWFhveUg0N21WVXdUNTl0elNGUlc4eURIIiwiZW5jb2RpbmciOiJiYXNlNTgiLCJmb3JtYXQiOiJzczU4IiwidHlwZSI6IlNyMjU1MTkifSwic2lnbmF0dXJlIjp7ImFsZ28iOiJTUjI1NTE5IiwiZW5jb2RpbmciOiJiYXNlMTYiLCJlbmNvZGVkVmFsdWUiOiIweDNlMTdhYzM3Yzk3ZWE3M2E3YzM1ZjBjYTJkZTcxYmY3MmE5NjlkYjhiNjQyYzU3ZTI2N2Q4N2Q1OTA3ZGM4MzVmYTJjODI4MTdlODA2YTQ5NGIyY2E5Y2U5MjJmNDM1NDY4M2U4YzAxMzY5NTNlMGZlNWExODJkMzU0NjQ2Yzg4In0sInBheWxvYWQiOnsiY2FsbGJhY2siOiJodHRwOi8vbG9jYWxob3N0OjMwMDAiLCJwZXJtaXNzaW9ucyI6WzUsNyw4LDksMTBdfX0sInJlcXVlc3RlZENyZWRlbnRpYWxzIjpbeyJ0eXBlIjoiVmVyaWZpZWRHcmFwaEtleUNyZWRlbnRpYWwiLCJoYXNoIjpbImJjaXFtZHZteGQ1NHp2ZTVraWZ5Y2dzZHRvYWhzNWVjZjRoYWwydHMzZWV4a2dvY3ljNW9jYTJ5Il19LHsiYW55T2YiOlt7InR5cGUiOiJWZXJpZmllZEVtYWlsQWRkcmVzc0NyZWRlbnRpYWwiLCJoYXNoIjpbImJjaXFlNHFvY3poZnRpY2k0ZHpmdmZiZWw3Zm80aDRzcjVncmNvM29vdnd5azZ5NHluZjQ0dHNpIl19LHsidHlwZSI6IlZlcmlmaWVkUGhvbmVOdW1iZXJDcmVkZW50aWFsIiwiaGFzaCI6WyJiY2lxanNwbmJ3cGMzd2p4NGZld2NlazVkYXlzZGpwYmY1eGppbXo1d251NXVqN2UzdnUydXducSJdfV19XX0&mode=dark"
33
```

docs/src/DataStructures/Response-LoginOnly.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
"encodedValue": "f6akufkq9Lex6rT8RCEDRuoZQRgo5pWiRzeo81nmKNGWGNJdJ",
55
"encoding": "base58",
66
"format": "ss58",
7-
"type": "SR25519"
7+
"type": "Sr25519"
88
},
99
"payloads": [
1010
{

docs/src/DataStructures/Response-NewProvider.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
"encodedValue": "f6akufkq9Lex6rT8RCEDRuoZQRgo5pWiRzeo81nmKNGWGNJdJ",
55
"encoding": "base58",
66
"format": "ss58",
7-
"type": "SR25519"
7+
"type": "Sr25519"
88
},
99
"payloads": [
1010
{

docs/src/DataStructures/Response-NewUser.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
"encodedValue": "f6akufkq9Lex6rT8RCEDRuoZQRgo5pWiRzeo81nmKNGWGNJdJ",
55
"encoding": "base58",
66
"format": "ss58",
7-
"type": "SR25519"
7+
"type": "Sr25519"
88
},
99
"payloads": [
1010
{

docs/src/DataStructures/SignedRequest.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55
"encodedValue": "f6cL4wq1HUNx11TcvdABNf9UNXXoyH47mVUwT59tzSFRW8yDH",
66
"encoding": "base58",
77
"format": "ss58",
8-
"type": "SR25519"
8+
"type": "Sr25519"
99
},
1010
"signature": {
1111
"algo": "SR25519",

libraries/js/package-lock.json

Lines changed: 4 additions & 4 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

libraries/js/package.json

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
{
22
"name": "@projectlibertylabs/siwf",
33
"version": "0.0.0",
4-
"description": "Sign In With Access Utility Library",
4+
"description": "Sign In With Frequency Utility Library",
55
"main": "src/index.ts",
66
"type": "module",
77
"scripts": {
@@ -38,7 +38,7 @@
3838
"eslint": "^9.12.0",
3939
"prettier": "3.3.3",
4040
"tsup": "^8.3.0",
41-
"typescript": "^5.6.2",
41+
"typescript": "^5.6.3",
4242
"typescript-eslint": "^8.8.1",
4343
"vitest": "^2.1.2"
4444
},

libraries/js/src/mocks/generate-data-structures.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@ function exampleSignedRequest(): SiwfSignedRequest {
2929
encodedValue: 'f6cL4wq1HUNx11TcvdABNf9UNXXoyH47mVUwT59tzSFRW8yDH',
3030
encoding: 'base58',
3131
format: 'ss58',
32-
type: 'SR25519',
32+
type: 'Sr25519',
3333
},
3434
signature: {
3535
algo: 'SR25519',

libraries/js/src/mocks/index.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ export const ExampleUserPublicKey: SiwfPublicKey = {
1414
encodedValue: ExampleUserKey.public,
1515
encoding: 'base58',
1616
format: 'ss58',
17-
type: 'SR25519',
17+
type: 'Sr25519',
1818
};
1919

2020
// NOTICE: These mocks ALSO generate the `docs/DataStructure/[].md` files. Take care changing them

libraries/js/src/payloads.test.ts

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,43 @@ beforeAll(async () => {
2020

2121
describe('validatePayloads', () => {
2222
describe('Login Related Payloads', () => {
23+
it('Can verify Login Payload generated from FA using hash', async () => {
24+
await expect(
25+
validatePayloads(
26+
{
27+
userPublicKey: {
28+
encodedValue: '5HYHZ8e8kyLEBuEbsFa2bwKYbVSMgaUhymfRVgH7CuM4VCHv',
29+
encoding: 'base58',
30+
format: 'ss58',
31+
type: 'Sr25519',
32+
},
33+
payloads: [
34+
{
35+
signature: {
36+
algo: 'SR25519',
37+
encoding: 'base16',
38+
encodedValue:
39+
'0xa6da6fa47076fbf7b0aac57a246041a777c867d15571dad1fdd014f4f0477a7ca5a92f5c952a740791b4e360b2320e94a3f20e733e821ac4242b1de72fbc6a80',
40+
},
41+
type: 'login',
42+
payload: {
43+
message: `localhost wants you to sign in with your Frequency account:
44+
frequency:dev:5HYHZ8e8kyLEBuEbsFa2bwKYbVSMgaUhymfRVgH7CuM4VCHv
45+
46+
URI: http://localhost:3030/login/callback
47+
Version: 1
48+
Nonce: d83eba8e-05a3-4c9a-9901-a976e67278b6
49+
Chain ID: frequency:dev
50+
Issued At: 2024-10-10T18:40:37.344099626Z`,
51+
},
52+
},
53+
],
54+
},
55+
'localhost'
56+
)
57+
).resolves.toBeUndefined();
58+
});
59+
2360
it('Can verify a Generated Login Payload', async () => {
2461
await expect(
2562
validatePayloads(

libraries/js/src/payloads.ts

Lines changed: 68 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
1-
import { signatureVerify, cryptoWaitReady } from '@polkadot/util-crypto';
1+
import { signatureVerify, cryptoWaitReady, decodeAddress, blake2AsU8a } from '@polkadot/util-crypto';
2+
import { hexToU8a, stringToU8a, u8aToHex, u8aWrapBytes } from '@polkadot/util';
23
import {
34
isPayloadAddProvider,
45
isPayloadClaimHandle,
@@ -20,14 +21,17 @@ interface SiwxMessage {
2021
nonce: string;
2122
expired: boolean;
2223
issuedAt: Date;
23-
expirationTime: Date;
24+
expirationTime?: Date;
2425
uri: string;
2526
}
2627

2728
function parseMessage(message: string): SiwxMessage {
2829
const msgSplit = message.split('\n');
2930
const domain = (msgSplit[0] || '').split(' ')[0] || '';
30-
const address = msgSplit[1] || '';
31+
32+
const addressLines = (msgSplit[1] || '').split(':');
33+
const address = addressLines[addressLines.length - 1] || '';
34+
3135
const nonceLine = msgSplit.find((x) => x.startsWith('Nonce: '));
3236
const nonce = nonceLine ? nonceLine.replace('Nonce: ', '') : '';
3337

@@ -36,8 +40,8 @@ function parseMessage(message: string): SiwxMessage {
3640

3741
const expiredLine = msgSplit.find((x) => x.startsWith('Expiration Time: '));
3842
const expiredString = expiredLine ? expiredLine.replace('Expiration Time: ', '') : '';
39-
const expirationTime = new Date(expiredString);
40-
const expired = +expirationTime < Date.now();
43+
const expirationTime = expiredString ? new Date(expiredString) : undefined;
44+
const expired = expirationTime ? +expirationTime < Date.now() : false;
4145

4246
const issuedLine = msgSplit.find((x) => x.startsWith('Issued At: '));
4347
const issuedString = issuedLine ? issuedLine.replace('Issued At: ', '') : '';
@@ -54,6 +58,36 @@ function parseMessage(message: string): SiwxMessage {
5458
};
5559
}
5660

61+
// SIWA is switching away from this, but we should still support it for now
62+
function verifySignatureHashMaybeWrapped(publicKey: string, signature: string, message: Uint8Array): boolean {
63+
const unwrappedSigned = message.length > 256 ? blake2AsU8a(message) : message;
64+
65+
const unwrappedVerifyResult = signatureVerify(unwrappedSigned, signature, publicKey);
66+
if (unwrappedVerifyResult.isValid) {
67+
return true;
68+
}
69+
70+
// Support both wrapped and unwrapped signatures
71+
const wrappedSignedBytes = u8aWrapBytes(message);
72+
const wrappedSigned = wrappedSignedBytes.length > 256 ? blake2AsU8a(wrappedSignedBytes) : wrappedSignedBytes;
73+
const wrappedVerifyResult = signatureVerify(wrappedSigned, signature, publicKey);
74+
75+
return wrappedVerifyResult.isValid;
76+
}
77+
78+
function verifySignatureMaybeWrapped(publicKey: string, signature: string, message: Uint8Array): boolean {
79+
const unwrappedVerifyResult = signatureVerify(message, signature, publicKey);
80+
if (unwrappedVerifyResult.isValid) {
81+
return true;
82+
}
83+
84+
// Support both wrapped and unwrapped signatures
85+
const wrappedSignedBytes = u8aWrapBytes(message);
86+
const wrappedVerifyResult = signatureVerify(wrappedSignedBytes, signature, publicKey);
87+
88+
return wrappedVerifyResult.isValid || verifySignatureHashMaybeWrapped(publicKey, signature, message);
89+
}
90+
5791
function expect(test: boolean, errorMessage: string) {
5892
if (!test) throw new Error(errorMessage);
5993
}
@@ -64,31 +98,41 @@ function validateLoginPayload(
6498
loginMsgDomain: string
6599
): void {
66100
// Check that the userPublicKey signed the message
67-
const signedMessage = payload.payload.message;
68-
const verifyResult = signatureVerify(signedMessage, payload.signature.encodedValue, userPublicKey.encodedValue);
69-
70-
expect(verifyResult.isValid, 'Login message signature failed');
101+
expect(
102+
verifySignatureMaybeWrapped(
103+
userPublicKey.encodedValue,
104+
payload.signature.encodedValue,
105+
stringToU8a(payload.payload.message)
106+
),
107+
'Login message signature failed'
108+
);
71109

72110
// Validate the message contents
73-
const msg = parseMessage(signedMessage);
111+
const msg = parseMessage(payload.payload.message);
74112
expect(
75113
msg.domain === loginMsgDomain,
76114
`Message does not match expected domain. Message: ${msg.domain} Expected: ${loginMsgDomain}`
77115
);
78-
expect(
79-
msg.address === userPublicKey.encodedValue,
80-
`Message does not match expected user public key value. Message: ${msg.address}`
81-
);
116+
// Match address encoding before comparing
117+
// decodeAddress will throw if it cannot decode meaning bad address
118+
try {
119+
const msgAddr = decodeAddress(msg.address);
120+
const userAddr = decodeAddress(userPublicKey.encodedValue);
121+
// Hex for easy comparison
122+
expect(u8aToHex(msgAddr) === u8aToHex(userAddr), 'Address mismatch');
123+
} catch (_e) {
124+
throw new Error(
125+
`Invalid address or message does not match bytes of expected user public key value. Message: ${msg.address} User: ${userPublicKey.encodedValue}`
126+
);
127+
}
82128

83-
expect(
84-
!msg.expired,
85-
`Message does not match expected user public key value. Message: ${msg.expirationTime.toISOString()}`
86-
);
129+
if (msg.expirationTime) {
130+
expect(!msg.expired, `Message has expired. Message: ${msg.expirationTime.toISOString()}`);
131+
}
87132
}
88133

89-
function validateSignature(key: string, signature: string, message: string) {
90-
const verifyResult = signatureVerify(message, signature, key);
91-
expect(verifyResult.isValid, 'Payload signature failed');
134+
function validateExtrinsicPayloadSignature(key: string, signature: string, message: string) {
135+
expect(verifySignatureMaybeWrapped(key, signature, hexToU8a(message)), 'Payload signature failed');
92136
}
93137

94138
export async function validatePayloads(response: SiwfResponse, loginMsgDomain: string): Promise<void> {
@@ -99,19 +143,19 @@ export async function validatePayloads(response: SiwfResponse, loginMsgDomain: s
99143
case isPayloadLogin(payload):
100144
return validateLoginPayload(payload, response.userPublicKey, loginMsgDomain);
101145
case isPayloadAddProvider(payload):
102-
return validateSignature(
146+
return validateExtrinsicPayloadSignature(
103147
response.userPublicKey.encodedValue,
104148
payload.signature.encodedValue,
105149
serializeAddProviderPayloadHex(payload.payload)
106150
);
107151
case isPayloadClaimHandle(payload):
108-
return validateSignature(
152+
return validateExtrinsicPayloadSignature(
109153
response.userPublicKey.encodedValue,
110154
payload.signature.encodedValue,
111155
serializeClaimHandlePayloadHex(payload.payload)
112156
);
113157
case isPayloadItemActions(payload):
114-
return validateSignature(
158+
return validateExtrinsicPayloadSignature(
115159
response.userPublicKey.encodedValue,
116160
payload.signature.encodedValue,
117161
serializeItemActionsPayloadHex(payload.payload)

libraries/js/src/request.test.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@ describe('request', () => {
2727
encodedValue: 'f6cL4wq1HUNx11TcvdABNf9UNXXoyH47mVUwT59tzSFRW8yDH',
2828
encoding: 'base58',
2929
format: 'ss58',
30-
type: 'SR25519',
30+
type: 'Sr25519',
3131
},
3232
signature: {
3333
algo: 'SR25519',
@@ -96,7 +96,7 @@ describe('request', () => {
9696
encodedValue: 'f6cL4wq1HUNx11TcvdABNf9UNXXoyH47mVUwT59tzSFRW8yDH',
9797
encoding: 'base58',
9898
format: 'ss58',
99-
type: 'SR25519',
99+
type: 'Sr25519',
100100
},
101101
},
102102
});

libraries/js/src/request.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -107,7 +107,7 @@ export function buildSignedRequest(
107107
encodedValue: encodeAddress(signerPublicKey, 90),
108108
encoding: 'base58',
109109
format: 'ss58',
110-
type: 'SR25519',
110+
type: 'Sr25519',
111111
},
112112
signature: {
113113
algo: 'SR25519',

libraries/js/src/response.test.ts

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -84,4 +84,11 @@ describe('validateSiwfResponse', () => {
8484
'Response failed to correctly parse or invalid content: {"foo":"bad"}'
8585
);
8686
});
87+
88+
it('throws on a bad domain', async () => {
89+
const example = await ExampleLogin();
90+
await expect(validateSiwfResponse(base64url(JSON.stringify(example)), 'bad.example.xyz')).to.rejects.toThrowError(
91+
'Message does not match expected domain. Message: localhost Expected: bad.example.xyz'
92+
);
93+
});
8794
});

libraries/js/src/types/general.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ export interface SiwfPublicKey {
99
encodedValue: string;
1010
encoding: 'base58';
1111
format: 'ss58';
12-
type: 'SR25519';
12+
type: 'Sr25519';
1313
}
1414

1515
// eslint-disable-next-line @typescript-eslint/no-explicit-any

0 commit comments

Comments
 (0)