-
Notifications
You must be signed in to change notification settings - Fork 0
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Bug: Domain only validation doesn't work for custom schemes #205
Changes from all commits
11f837f
a332dc1
9312f42
c0f3043
c85b0a3
4530b6d
6fb4c17
78044a5
999b3bc
06f5b0d
f23fc87
8528a49
f5fd375
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -96,7 +96,8 @@ No submission to the chain is required, but the application *must* validate the | |
The message signed follows [CAIP-122: Sign in With X](https://chainagnostic.org/CAIPs/caip-122) specification which is derived from [EIP-4361: Sign-In with Ethereum](https://eips.ethereum.org/EIPS/eip-4361). | ||
|
||
#### Example Message with Placeholders | ||
``` | ||
|
||
```text | ||
{{domain}} wants you to sign in with your Frequency account: | ||
frequency:{{chainReference}}:{{ss58Address}} | ||
|
||
|
@@ -107,7 +108,10 @@ Chain ID: frequency:{{chainReference}} | |
Issued At: {{issued-at}} | ||
``` | ||
|
||
Inside the message, `{{domain}}` is the domain of the application requesting the sign-in. `{{domain}}` should match the domain contained in the `URI` field. | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Domain clarification |
||
|
||
#### Validation Steps | ||
|
||
1. Perform an Sr25519 signature verification using: | ||
- `userPublicKey`: The signing key | ||
- `payload.message`: The signed message parsing `\n` into `LF` line breaks | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,6 +1,6 @@ | ||
```json | ||
{ | ||
"signedRequest": "eyJyZXF1ZXN0ZWRTaWduYXR1cmVzIjp7InB1YmxpY0tleSI6eyJlbmNvZGVkVmFsdWUiOiJmNmNMNHdxMUhVTngxMVRjdmRBQk5mOVVOWFhveUg0N21WVXdUNTl0elNGUlc4eURIIiwiZW5jb2RpbmciOiJiYXNlNTgiLCJmb3JtYXQiOiJzczU4IiwidHlwZSI6IlNyMjU1MTkifSwic2lnbmF0dXJlIjp7ImFsZ28iOiJTUjI1NTE5IiwiZW5jb2RpbmciOiJiYXNlMTYiLCJlbmNvZGVkVmFsdWUiOiIweDNlMTdhYzM3Yzk3ZWE3M2E3YzM1ZjBjYTJkZTcxYmY3MmE5NjlkYjhiNjQyYzU3ZTI2N2Q4N2Q1OTA3ZGM4MzVmYTJjODI4MTdlODA2YTQ5NGIyY2E5Y2U5MjJmNDM1NDY4M2U4YzAxMzY5NTNlMGZlNWExODJkMzU0NjQ2Yzg4In0sInBheWxvYWQiOnsiY2FsbGJhY2siOiJodHRwOi8vbG9jYWxob3N0OjMwMDAiLCJwZXJtaXNzaW9ucyI6WzUsNyw4LDksMTBdfX0sInJlcXVlc3RlZENyZWRlbnRpYWxzIjpbeyJ0eXBlIjoiVmVyaWZpZWRHcmFwaEtleUNyZWRlbnRpYWwiLCJoYXNoIjpbImJjaXFtZHZteGQ1NHp2ZTVraWZ5Y2dzZHRvYWhzNWVjZjRoYWwydHMzZWV4a2dvY3ljNW9jYTJ5Il19LHsiYW55T2YiOlt7InR5cGUiOiJWZXJpZmllZEVtYWlsQWRkcmVzc0NyZWRlbnRpYWwiLCJoYXNoIjpbImJjaXFlNHFvY3poZnRpY2k0ZHpmdmZiZWw3Zm80aDRzcjVncmNvM29vdnd5azZ5NHluZjQ0dHNpIl19LHsidHlwZSI6IlZlcmlmaWVkUGhvbmVOdW1iZXJDcmVkZW50aWFsIiwiaGFzaCI6WyJiY2lxanNwbmJ3cGMzd2p4NGZld2NlazVkYXlzZGpwYmY1eGppbXo1d251NXVqN2UzdnUydXducSJdfV19XX0", | ||
"signedRequest": "eyJyZXF1ZXN0ZWRTaWduYXR1cmVzIjp7InB1YmxpY0tleSI6eyJlbmNvZGVkVmFsdWUiOiJmNmNMNHdxMUhVTngxMVRjdmRBQk5mOVVOWFhveUg0N21WVXdUNTl0elNGUlc4eURIIiwiZW5jb2RpbmciOiJiYXNlNTgiLCJmb3JtYXQiOiJzczU4IiwidHlwZSI6IlNyMjU1MTkifSwic2lnbmF0dXJlIjp7ImFsZ28iOiJTUjI1NTE5IiwiZW5jb2RpbmciOiJiYXNlMTYiLCJlbmNvZGVkVmFsdWUiOiIweDk2MGYxOTVkYzFmOTFiZjcxYzBiMzUyMzE1MGFlMzc0NzFiZWRlMDdhMDAzOTA5NjQ3Y2NmMDQwYWNkNWNkMDRlYTQ4NzBiZDEyNGNhZmEyZGViNTliMGUzNzhjYjE5ZmJjNmFmNjAxYjc1NTU5ZmFhYjdiNzY4ZGU4MWEwOTgzIn0sInBheWxvYWQiOnsiY2FsbGJhY2siOiJodHRwOi8vbG9jYWxob3N0OjMwMDAiLCJwZXJtaXNzaW9ucyI6WzUsNyw4LDksMTBdfX0sInJlcXVlc3RlZENyZWRlbnRpYWxzIjpbeyJ0eXBlIjoiVmVyaWZpZWRHcmFwaEtleUNyZWRlbnRpYWwiLCJoYXNoIjpbImJjaXFtZHZteGQ1NHp2ZTVraWZ5Y2dzZHRvYWhzNWVjZjRoYWwydHMzZWV4a2dvY3ljNW9jYTJ5Il19LHsiYW55T2YiOlt7InR5cGUiOiJWZXJpZmllZEVtYWlsQWRkcmVzc0NyZWRlbnRpYWwiLCJoYXNoIjpbImJjaXFlNHFvY3poZnRpY2k0ZHpmdmZiZWw3Zm80aDRzcjVncmNvM29vdnd5azZ5NHluZjQ0dHNpIl19LHsidHlwZSI6IlZlcmlmaWVkUGhvbmVOdW1iZXJDcmVkZW50aWFsIiwiaGFzaCI6WyJiY2lxanNwbmJ3cGMzd2p4NGZld2NlazVkYXlzZGpwYmY1eGppbXo1d251NXVqN2UzdnUydXducSJdfV19XX0", | ||
"mode": "dark" | ||
} | ||
``` |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,3 +1,3 @@ | ||
```json | ||
"https://testnet.frequencyaccess.com/siwa/start?signedRequest=eyJyZXF1ZXN0ZWRTaWduYXR1cmVzIjp7InB1YmxpY0tleSI6eyJlbmNvZGVkVmFsdWUiOiJmNmNMNHdxMUhVTngxMVRjdmRBQk5mOVVOWFhveUg0N21WVXdUNTl0elNGUlc4eURIIiwiZW5jb2RpbmciOiJiYXNlNTgiLCJmb3JtYXQiOiJzczU4IiwidHlwZSI6IlNyMjU1MTkifSwic2lnbmF0dXJlIjp7ImFsZ28iOiJTUjI1NTE5IiwiZW5jb2RpbmciOiJiYXNlMTYiLCJlbmNvZGVkVmFsdWUiOiIweDNlMTdhYzM3Yzk3ZWE3M2E3YzM1ZjBjYTJkZTcxYmY3MmE5NjlkYjhiNjQyYzU3ZTI2N2Q4N2Q1OTA3ZGM4MzVmYTJjODI4MTdlODA2YTQ5NGIyY2E5Y2U5MjJmNDM1NDY4M2U4YzAxMzY5NTNlMGZlNWExODJkMzU0NjQ2Yzg4In0sInBheWxvYWQiOnsiY2FsbGJhY2siOiJodHRwOi8vbG9jYWxob3N0OjMwMDAiLCJwZXJtaXNzaW9ucyI6WzUsNyw4LDksMTBdfX0sInJlcXVlc3RlZENyZWRlbnRpYWxzIjpbeyJ0eXBlIjoiVmVyaWZpZWRHcmFwaEtleUNyZWRlbnRpYWwiLCJoYXNoIjpbImJjaXFtZHZteGQ1NHp2ZTVraWZ5Y2dzZHRvYWhzNWVjZjRoYWwydHMzZWV4a2dvY3ljNW9jYTJ5Il19LHsiYW55T2YiOlt7InR5cGUiOiJWZXJpZmllZEVtYWlsQWRkcmVzc0NyZWRlbnRpYWwiLCJoYXNoIjpbImJjaXFlNHFvY3poZnRpY2k0ZHpmdmZiZWw3Zm80aDRzcjVncmNvM29vdnd5azZ5NHluZjQ0dHNpIl19LHsidHlwZSI6IlZlcmlmaWVkUGhvbmVOdW1iZXJDcmVkZW50aWFsIiwiaGFzaCI6WyJiY2lxanNwbmJ3cGMzd2p4NGZld2NlazVkYXlzZGpwYmY1eGppbXo1d251NXVqN2UzdnUydXducSJdfV19XX0&mode=dark" | ||
"https://testnet.frequencyaccess.com/siwa/start?signedRequest=eyJyZXF1ZXN0ZWRTaWduYXR1cmVzIjp7InB1YmxpY0tleSI6eyJlbmNvZGVkVmFsdWUiOiJmNmNMNHdxMUhVTngxMVRjdmRBQk5mOVVOWFhveUg0N21WVXdUNTl0elNGUlc4eURIIiwiZW5jb2RpbmciOiJiYXNlNTgiLCJmb3JtYXQiOiJzczU4IiwidHlwZSI6IlNyMjU1MTkifSwic2lnbmF0dXJlIjp7ImFsZ28iOiJTUjI1NTE5IiwiZW5jb2RpbmciOiJiYXNlMTYiLCJlbmNvZGVkVmFsdWUiOiIweDk2MGYxOTVkYzFmOTFiZjcxYzBiMzUyMzE1MGFlMzc0NzFiZWRlMDdhMDAzOTA5NjQ3Y2NmMDQwYWNkNWNkMDRlYTQ4NzBiZDEyNGNhZmEyZGViNTliMGUzNzhjYjE5ZmJjNmFmNjAxYjc1NTU5ZmFhYjdiNzY4ZGU4MWEwOTgzIn0sInBheWxvYWQiOnsiY2FsbGJhY2siOiJodHRwOi8vbG9jYWxob3N0OjMwMDAiLCJwZXJtaXNzaW9ucyI6WzUsNyw4LDksMTBdfX0sInJlcXVlc3RlZENyZWRlbnRpYWxzIjpbeyJ0eXBlIjoiVmVyaWZpZWRHcmFwaEtleUNyZWRlbnRpYWwiLCJoYXNoIjpbImJjaXFtZHZteGQ1NHp2ZTVraWZ5Y2dzZHRvYWhzNWVjZjRoYWwydHMzZWV4a2dvY3ljNW9jYTJ5Il19LHsiYW55T2YiOlt7InR5cGUiOiJWZXJpZmllZEVtYWlsQWRkcmVzc0NyZWRlbnRpYWwiLCJoYXNoIjpbImJjaXFlNHFvY3poZnRpY2k0ZHpmdmZiZWw3Zm80aDRzcjVncmNvM29vdnd5azZ5NHluZjQ0dHNpIl19LHsidHlwZSI6IlZlcmlmaWVkUGhvbmVOdW1iZXJDcmVkZW50aWFsIiwiaGFzaCI6WyJiY2lxanNwbmJ3cGMzd2p4NGZld2NlazVkYXlzZGpwYmY1eGppbXo1d251NXVqN2UzdnUydXducSJdfV19XX0&mode=dark" | ||
``` |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -12,38 +12,52 @@ import { | |
serializeItemActionsPayloadHex, | ||
} from '../util.js'; | ||
|
||
function generateLoginMessage(account: string, issued: Date, expires: Date, domain: string) { | ||
return `${domain} wants you to sign in with your Frequency account:\n${account}\n\n\n\nURI: https://testnet.frequencyaccess.com/signin/confirm\nNonce: N6rLwqyz34oUxJEXJ\nIssued At: ${issued.toISOString()}\nExpiration Time: ${expires.toISOString()}`; | ||
function generateLoginMessage(account: string, issued: Date, expires: Date, uri: URL) { | ||
return `${uri.hostname} wants you to sign in with your Frequency account:\n${account}\n\n\n\nURI: ${uri}\nNonce: N6rLwqyz34oUxJEXJ\nIssued At: ${issued.toISOString()}\nExpiration Time: ${expires.toISOString()}`; | ||
} | ||
|
||
// Setup now so that it is consistent for the entire test run | ||
const now = Date.now(); | ||
|
||
const loginMessageGood = (domain: string) => | ||
const loginMessageUrl = (url: string) => | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Allows to build test cases with different urls |
||
generateLoginMessage( | ||
ExampleUserKey.public, | ||
new Date(now - 24 * 60 * 60 * 1000), | ||
new Date(now + 24 * 60 * 60 * 1000), | ||
domain | ||
new URL(url) | ||
); | ||
|
||
const loginMessageGood = () => loginMessageUrl('https://your-app.com/signin/callback'); | ||
|
||
const loginMessageExpired = () => | ||
generateLoginMessage( | ||
ExampleUserKey.public, | ||
new Date(now - 2 * 24 * 60 * 60 * 1000), | ||
new Date(now - 24 * 60 * 60 * 1000), | ||
'localhost' | ||
new URL('https://your-app.com/signin/callback') | ||
); | ||
|
||
export const ExamplePayloadLoginGood = (domain: string): SiwfResponsePayloadLogin => ({ | ||
export const ExamplePayloadLoginUrl = (url: string): SiwfResponsePayloadLogin => ({ | ||
signature: { | ||
algo: 'SR25519', | ||
encoding: 'base16', | ||
encodedValue: u8aToHex(ExampleUserKey.keyPair().sign(loginMessageUrl(url))), | ||
}, | ||
type: 'login', | ||
payload: { | ||
message: loginMessageUrl(url), | ||
}, | ||
}); | ||
|
||
export const ExamplePayloadLoginGood = (): SiwfResponsePayloadLogin => ({ | ||
signature: { | ||
algo: 'SR25519', | ||
encoding: 'base16', | ||
encodedValue: u8aToHex(ExampleUserKey.keyPair().sign(loginMessageGood(domain))), | ||
encodedValue: u8aToHex(ExampleUserKey.keyPair().sign(loginMessageGood())), | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. domain will always match the URI in the test cases |
||
}, | ||
type: 'login', | ||
payload: { | ||
message: loginMessageGood(domain), | ||
message: loginMessageGood(), | ||
}, | ||
}); | ||
|
||
|
@@ -64,12 +78,20 @@ export const ExamplePayloadLoginStatic: SiwfResponsePayloadLogin = { | |
algo: 'SR25519', | ||
encoding: 'base16', | ||
encodedValue: | ||
'0x84a4e03344b07d64087ebdf47b2c8c679aa7de78179689988992609f1b83c34f6086c7de99ef41c5325cce64d148624e716c605d355f22d1281f6d23f546f584', | ||
'0xe261698297111834e68b4152bf1f89819e886b6528f6fff45715f7781d0f1e7dc4007ccfed1e85b8c603c0fea2f7abf22bfe6336869ad21f11a09a114452c680', | ||
}, | ||
type: 'login', | ||
payload: { | ||
message: | ||
'localhost wants you to sign in with your Frequency account:\nf6akufkq9Lex6rT8RCEDRuoZQRgo5pWiRzeo81nmKNGWGNJdJ\n\n\n\nURI: https://testnet.frequencyaccess.com/signin/confirm\nNonce: N6rLwqyz34oUxJEXJ\nIssued At: 2024-03-05T23:18:03.041Z\nExpiration Time: 2060-03-05T23:23:03.041Z', | ||
'your-app.com wants you to sign in with your Frequency account:\n' + | ||
'f6akufkq9Lex6rT8RCEDRuoZQRgo5pWiRzeo81nmKNGWGNJdJ\n' + | ||
'\n' + | ||
'\n' + | ||
'\n' + | ||
'URI: https://your-app.com/signin/callback\n' + | ||
'Nonce: N6rLwqyz34oUxJEXJ\n' + | ||
'Issued At: 2024-10-29T19:17:27.077Z\n' + | ||
'Expiration Time: 2060-03-05T23:23:03.041Z', | ||
}, | ||
}; | ||
|
||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
❤️