Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 8 additions & 3 deletions src/utils/type-guards.ts
Original file line number Diff line number Diff line change
Expand Up @@ -25,16 +25,21 @@ function isNil(value: any): value is null | undefined {
return isNull(value) || isUndefined(value);
}

/** Unix-second claim fields must be finite numbers. Strings/NaN fail-open in `<` / `-`. */
function isFiniteNumber(value: any): value is number {
return typeof value === 'number' && Number.isFinite(value);
}

/** Assert `value` contains all required DID Token members. */
export function isDIDTClaim(value: any): value is Claim {
return (
!isNil(value) &&
!isNil(value.iat) &&
!isNil(value.ext) &&
isFiniteNumber(value.iat) &&
isFiniteNumber(value.ext) &&
!isNil(value.iss) &&
!isNil(value.sub) &&
!isNil(value.aud) &&
!isNil(value.nbf) &&
isFiniteNumber(value.nbf) &&
!isNil(value.tid) &&
!isNil(value.add)
);
Expand Down
22 changes: 22 additions & 0 deletions test/spec/modules/token/validate.spec.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import { Wallet } from 'ethers';
import { createMagicAdminSDK } from '../../../lib/factories';
import {
VALID_DIDT,
Expand Down Expand Up @@ -67,3 +68,24 @@ test('Fails if aud is incorrect', async () => {
const expectedError = createAudienceMismatchError();
expect(() => sdk.token.validate(VALID_DIDT)).toThrow(expectedError);
});

test('Fails when `ext` is present but not a finite number', async () => {
const wallet = Wallet.createRandom();
const now = Math.floor(Date.now() / 1000);
const claim = JSON.stringify({
iat: now,
ext: 'never',
iss: `did:ethr:${wallet.address}`,
sub: 'test-sub',
aud: 'did:magic:test',
nbf: now,
tid: 'test-tid',
add: '0x00',
});
const proof = await wallet.signMessage(claim);
const didToken = Buffer.from(JSON.stringify([proof, claim])).toString('base64');

const sdk = createMagicAdminSDK();
const expectedError = createMalformedTokenError();
expect(() => sdk.token.validate(didToken)).toThrow(expectedError);
});
16 changes: 16 additions & 0 deletions test/spec/utils/parse-didt.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,3 +11,19 @@ test('Throws error if token is malformed', async () => {
const expectedError = createMalformedTokenError();
expect(() => parseDIDToken(INVALID_DIDT_MALFORMED_CLAIM)).toThrow(expectedError);
});

test('Throws error if `ext` is not a finite number', async () => {
const claim = JSON.stringify({
iat: 123,
ext: 'never',
iss: 'did:ethr:0x0000000000000000000000000000000000000001',
sub: 'sub',
aud: 'aud',
nbf: 123,
tid: 'tid',
add: '0x00',
});
const token = Buffer.from(JSON.stringify(['0x00', claim])).toString('base64');
const expectedError = createMalformedTokenError();
expect(() => parseDIDToken(token)).toThrow(expectedError);
});
60 changes: 60 additions & 0 deletions test/spec/utils/type-guards/isDIDTClaim.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -59,3 +59,63 @@ test('Returns true given with all required properties', async () => {
isDIDTClaim({ iat: 123, ext: 123, iss: 'asdf', sub: 'asdf', aud: 'asdf', nbf: 123, tid: 'asdf', add: '0x0123' }),
).toBe(true);
});

test('Returns false given non-numeric `Claim.ext`', async () => {
expect(
isDIDTClaim({
iat: 123,
ext: 'never',
iss: 'asdf',
sub: 'asdf',
aud: 'asdf',
nbf: 123,
tid: 'asdf',
add: '0x0123',
}),
).toBe(false);
});

test('Returns false given non-numeric `Claim.nbf`', async () => {
expect(
isDIDTClaim({
iat: 123,
ext: 123,
iss: 'asdf',
sub: 'asdf',
aud: 'asdf',
nbf: 'later',
tid: 'asdf',
add: '0x0123',
}),
).toBe(false);
});

test('Returns false given non-numeric `Claim.iat`', async () => {
expect(
isDIDTClaim({
iat: 'yesterday',
ext: 123,
iss: 'asdf',
sub: 'asdf',
aud: 'asdf',
nbf: 123,
tid: 'asdf',
add: '0x0123',
}),
).toBe(false);
});

test('Returns false given non-finite `Claim.ext`', async () => {
expect(
isDIDTClaim({
iat: 123,
ext: Number.NaN,
iss: 'asdf',
sub: 'asdf',
aud: 'asdf',
nbf: 123,
tid: 'asdf',
add: '0x0123',
}),
).toBe(false);
});