Skip to content

Commit

Permalink
feat: add utility function for decoding abax profile id token (#33)
Browse files Browse the repository at this point in the history
* feat: add utility function for decoding abax profile id token

* test: add test to decode function
  • Loading branch information
braaar authored Aug 8, 2023
1 parent 0b828e2 commit 0373a7f
Show file tree
Hide file tree
Showing 5 changed files with 129 additions and 1 deletion.
1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@
"dependencies": {
"date-fns": "^2.30.0",
"exponential-backoff": "^3.1.1",
"fast-jwt": "^3.1.1",
"ts-invariant": "^0.10.3",
"typical-fetch": "^2.0.0",
"zod": "^3.21.4"
Expand Down
54 changes: 53 additions & 1 deletion pnpm-lock.yaml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

39 changes: 39 additions & 0 deletions src/authentication/__tests__/decode-abax-profile.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
import { describe, expect, it } from 'vitest';
import { decodeAbaxProfileToken } from '../decode-abax-profile';

describe('decode-abax.profile.ts', () => {
it('should be able to decode a JWT id token correctly', () => {
const token =
'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJodHRwczovL2lkZW50aXR5LmFiYXguY2xvdWQiLCJuYmYiOjEyMywiaWF0IjoxMjMsImV4cCI6MTIzLCJhdWQiOiJoZWxsbyIsImFtciI6WyJoZWxsbyJdLCJhdF9oYXNoIjoiMTIzYWJjIiwic2lkIjoiMTIzRUYiLCJzdWIiOiIxMjMiLCJhdXRoX3RpbWUiOjEyMywiaWRwIjoibG9jYWwiLCJodHRwOi8vc2NoZW1hcy5hYmF4Lm5vL2lkZW50aXR5L2NsYWltcy91c2VybmFtZSI6ImhlbGxvQGV4YW1wbGUuY29tIiwicm9sZSI6IkFkbWluaXN0cmF0b3IiLCJuYW1lIjoiTmFtZSBOYW1leSIsImxvY2FsZSI6Im5vIiwiaHR0cDovL3NjaGVtYXMuYWJheC5uby9pZGVudGl0eS9jbGFpbXMvb3JnYW5pemF0aW9uaWQiOiIxMjMiLCJodHRwOi8vc2NoZW1hcy5hYmF4Lm5vL2lkZW50aXR5L2NsYWltcy9jb3VudHJ5Y29kZSI6Ik5PIiwiZW1haWwiOiJoZWxsb0BleGFtcGxlLmNvbSIsImVtYWlsX3ZlcmlmaWVkIjp0cnVlLCJwaG9uZV9udW1iZXIiOiIrNDc5OTk5OTk5OSIsImh0dHA6Ly9zY2hlbWFzLmFiYXgubm8vaWRlbnRpdHkvY2xhaW1zL3NlY3VyaXR5c3RhbXAiOiIxMjNhYmMifQ.9NTEjVBPoFye2ZLu4OSSGc4j8fIpRFyEoJEFLw9-C2U';

const decoded = decodeAbaxProfileToken(token);

expect(decoded).toMatchObject({
iss: 'https://identity.abax.cloud',
nbf: 123,
iat: 123,
exp: 123,
aud: 'hello',
amr: ['hello'],
at_hash: '123abc',
sid: '123EF',
sub: '123',
auth_time: 123,
idp: 'local',
'http://schemas.abax.no/identity/claims/username': '[email protected]',
role: 'Administrator',
name: 'Name Namey',
locale: 'no',
'http://schemas.abax.no/identity/claims/organizationid': '123',
'http://schemas.abax.no/identity/claims/countrycode': 'NO',
email: '[email protected]',
email_verified: true,
phone_number: '+4799999999',
'http://schemas.abax.no/identity/claims/securitystamp': '123abc',
});
});
it('should fail to decode a bad token', () => {
const token = 'asdf';
expect(() => decodeAbaxProfileToken(token)).toThrow();
});
});
35 changes: 35 additions & 0 deletions src/authentication/decode-abax-profile.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
import { createDecoder } from 'fast-jwt';
import { z } from 'zod';

export const abaxIdTokenPayload = z.object({
iss: z.string(),
nbf: z.number(),
iat: z.number(),
exp: z.number(),
aud: z.string(),
amr: z.array(z.string()),
at_hash: z.string(),
sid: z.string(),
sub: z.string(),
auth_time: z.number(),
idp: z.string(),
'http://schemas.abax.no/identity/claims/username': z.string(),
role: z.string(),
name: z.string(),
locale: z.string(),
'http://schemas.abax.no/identity/claims/organizationid': z.string(),
'http://schemas.abax.no/identity/claims/countrycode': z.string(),
email: z.string(),
email_verified: z.boolean(),
phone_number: z.string(),
'http://schemas.abax.no/identity/claims/securitystamp': z.string(),
});

export type AbaxIdTokenPayload = z.infer<typeof abaxIdTokenPayload>;

/** Extract Abax Profile data from a JWT id token that was retrieved with the `abax_profile` scope. */
export function decodeAbaxProfileToken(idToken: string): AbaxIdTokenPayload {
const decode = createDecoder();

return abaxIdTokenPayload.parse(decode(idToken));
}
1 change: 1 addition & 0 deletions src/main.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,3 +10,4 @@ export * from './calls/list-equipment.js';
export * from './authentication/abax-auth.js';
export * from './authentication/types.js';
export type { AuthorizationCodeInput } from './authentication/calls.js';
export * from './authentication/decode-abax-profile.js';

0 comments on commit 0373a7f

Please sign in to comment.