-
Notifications
You must be signed in to change notification settings - Fork 2
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Signed-off-by: Berend Sliedrecht <[email protected]>
- Loading branch information
1 parent
ee9085d
commit 6f981c7
Showing
6 changed files
with
262 additions
and
18 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,27 @@ | ||
import { Hasher } from './sdJwt' | ||
import { OrPromise } from './types' | ||
|
||
/** | ||
* Key should not be used to generate the salt as it needs to be unique. It is used for testing here | ||
*/ | ||
export type SaltGenerator = () => OrPromise<string> | ||
|
||
const createDecoy = async (saltGenerator: SaltGenerator, hasher: Hasher) => { | ||
const salt = await saltGenerator() | ||
const decoy = await hasher(salt) | ||
|
||
return decoy | ||
} | ||
|
||
export const createDecoys = async ( | ||
count: number, | ||
saltGenerator: SaltGenerator, | ||
hasher: Hasher, | ||
) => { | ||
const decoys: Array<string> = [] | ||
for (let i = 0; i < count; i++) { | ||
const decoy = await createDecoy(saltGenerator, hasher) | ||
decoys.push(decoy) | ||
} | ||
return decoys | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,44 @@ | ||
import { SdJwtError } from './error' | ||
import { Base64url } from './base64url' | ||
|
||
export const createObjectDisclosure = ( | ||
salt: string, | ||
key: string, | ||
value: unknown, | ||
) => { | ||
if (typeof value === 'number' && isNaN(value)) { | ||
throw new SdJwtError('NaN is not allowed to be used in a disclosure.') | ||
} | ||
|
||
if (typeof value === 'number' && !isFinite(value)) { | ||
throw new SdJwtError( | ||
'Infinite is not allowed to be used in a disclosure.', | ||
) | ||
} | ||
|
||
if (Array.isArray(value)) { | ||
throw new SdJwtError( | ||
'Array is not allowed. Use `createArrayDisclosure()`.', | ||
) | ||
} | ||
|
||
const disclosure = [salt, key, value] | ||
|
||
return Base64url.encode(JSON.stringify(disclosure)) | ||
} | ||
|
||
export const createArrayDisclosure = (salt: string, value: unknown) => { | ||
if (typeof value === 'number' && isNaN(value)) { | ||
throw new SdJwtError('NaN is not allowed to be used in a disclosure.') | ||
} | ||
|
||
if (typeof value === 'number' && !isFinite(value)) { | ||
throw new SdJwtError( | ||
'Infinite is not allowed to be used in a disclosure.', | ||
) | ||
} | ||
|
||
const disclosure = [salt, value] | ||
|
||
return Base64url.encode(JSON.stringify(disclosure)) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Empty file.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,161 @@ | ||
import { describe, it } from 'node:test' | ||
|
||
import assert from 'node:assert' | ||
|
||
import { | ||
createArrayDisclosure, | ||
createObjectDisclosure, | ||
} from '../src/createDisclosure' | ||
import { c14n } from './utils' | ||
|
||
describe('createDisclosure', () => { | ||
describe('Specification Example 5.5', () => { | ||
it('Claim given_name', async () => { | ||
const disclosure = createObjectDisclosure( | ||
'2GLC42sKQveCfGfryNRN9w', | ||
'given_name', | ||
'John', | ||
) | ||
|
||
assert.strictEqual( | ||
c14n(disclosure), | ||
c14n( | ||
'WyIyR0xDNDJzS1F2ZUNmR2ZyeU5STjl3IiwgImdpdmVuX25hbWUiLCAiSm9obiJd', | ||
), | ||
) | ||
}) | ||
|
||
it('Claim family_name', async () => { | ||
const disclosure = createObjectDisclosure( | ||
'eluV5Og3gSNII8EYnsxA_A', | ||
'family_name', | ||
'Doe', | ||
) | ||
|
||
assert.strictEqual( | ||
c14n(disclosure), | ||
c14n( | ||
'WyJlbHVWNU9nM2dTTklJOEVZbnN4QV9BIiwgImZhbWlseV9uYW1lIiwgIkRvZSJd', | ||
), | ||
) | ||
}) | ||
|
||
it('Claim email', async () => { | ||
const disclosure = createObjectDisclosure( | ||
'6Ij7tM-a5iVPGboS5tmvVA', | ||
'email', | ||
'[email protected]', | ||
) | ||
|
||
assert.strictEqual( | ||
c14n(disclosure), | ||
c14n( | ||
'WyI2SWo3dE0tYTVpVlBHYm9TNXRtdlZBIiwgImVtYWlsIiwgImpvaG5kb2VAZXhhbXBsZS5jb20iXQ', | ||
), | ||
) | ||
}) | ||
|
||
it('Claim phone_number', async () => { | ||
const disclosure = createObjectDisclosure( | ||
'eI8ZWm9QnKPpNPeNenHdhQ', | ||
'phone_number', | ||
'+1-202-555-0101', | ||
) | ||
|
||
assert.strictEqual( | ||
c14n(disclosure), | ||
c14n( | ||
'WyJlSThaV205UW5LUHBOUGVOZW5IZGhRIiwgInBob25lX251bWJlciIsICIrMS0yMDItNTU1LTAxMDEiXQ', | ||
), | ||
) | ||
}) | ||
it('Claim phone_number_verified', async () => { | ||
const disclosure = createObjectDisclosure( | ||
'Qg_O64zqAxe412a108iroA', | ||
'phone_number_verified', | ||
true, | ||
) | ||
|
||
assert.strictEqual( | ||
c14n(disclosure), | ||
c14n( | ||
'WyJRZ19PNjR6cUF4ZTQxMmExMDhpcm9BIiwgInBob25lX251bWJlcl92ZXJpZmllZCIsIHRydWVd', | ||
), | ||
) | ||
}) | ||
|
||
it('Claim address', async () => { | ||
const disclosure = createObjectDisclosure( | ||
'AJx-095VPrpTtN4QMOqROA', | ||
'address', | ||
{ | ||
street_address: '123 Main St', | ||
locality: 'Anytown', | ||
region: 'Anystate', | ||
country: 'US', | ||
}, | ||
) | ||
|
||
assert.strictEqual( | ||
c14n(disclosure), | ||
c14n( | ||
'WyJBSngtMDk1VlBycFR0TjRRTU9xUk9BIiwgImFkZHJlc3MiLCB7InN0cmVldF9hZGRyZXNzIjogIjEyMyBNYWluIFN0IiwgImxvY2FsaXR5IjogIkFueXRvd24iLCAicmVnaW9uIjogIkFueXN0YXRlIiwgImNvdW50cnkiOiAiVVMifV0', | ||
), | ||
) | ||
}) | ||
|
||
it('Claim birthdate', async () => { | ||
const disclosure = createObjectDisclosure( | ||
'Pc33JM2LchcU_lHggv_ufQ', | ||
'birthdate', | ||
'1940-01-01', | ||
) | ||
|
||
assert.strictEqual( | ||
c14n(disclosure), | ||
c14n( | ||
'WyJQYzMzSk0yTGNoY1VfbEhnZ3ZfdWZRIiwgImJpcnRoZGF0ZSIsICIxOTQwLTAxLTAxIl0', | ||
), | ||
) | ||
}) | ||
|
||
it('Claim updated_at', async () => { | ||
const disclosure = createObjectDisclosure( | ||
'G02NSrQfjFXQ7Io09syajA', | ||
'updated_at', | ||
1570000000, | ||
) | ||
|
||
assert.strictEqual( | ||
c14n(disclosure), | ||
c14n( | ||
'WyJHMDJOU3JRZmpGWFE3SW8wOXN5YWpBIiwgInVwZGF0ZWRfYXQiLCAxNTcwMDAwMDAwXQ', | ||
), | ||
) | ||
}) | ||
|
||
it('Array Entry 01', async () => { | ||
const disclosure = createArrayDisclosure( | ||
'lklxF5jMYlGTPUovMNIvCA', | ||
'US', | ||
) | ||
|
||
assert.strictEqual( | ||
c14n(disclosure), | ||
c14n('WyJsa2x4RjVqTVlsR1RQVW92TU5JdkNBIiwgIlVTIl0'), | ||
) | ||
}) | ||
|
||
it('Array Entry 02', async () => { | ||
const disclosure = createArrayDisclosure( | ||
'nPuoQnkRFq3BIeAm7AnXFA', | ||
'DE', | ||
) | ||
|
||
assert.strictEqual( | ||
c14n(disclosure), | ||
c14n('WyJuUHVvUW5rUkZxM0JJZUFtN0FuWEZBIiwgIkRFIl0'), | ||
) | ||
}) | ||
}) | ||
}) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
import { Base64url } from '../src/base64url' | ||
|
||
export const c14n = (x: string) => JSON.stringify(Base64url.decodeToJson(x)) |