Skip to content

Commit

Permalink
Add 'UtilsModule' & 'parseAuthorizationHeader' helper (#39)
Browse files Browse the repository at this point in the history
* Add 'UtilModule' & 'parseTokenFromBearerString' helper

* Update CHANGELOG

* Rename 'UtilModule' to 'UtilsModule'

* Reflect nomenclature changes in CHANGELOG
  • Loading branch information
smithki authored May 25, 2020
1 parent a80ac73 commit 6affc13
Show file tree
Hide file tree
Showing 9 changed files with 68 additions and 1 deletion.
6 changes: 6 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,12 @@

- ...

## `1.1.0` - 05/25/2020

#### Added

- Introduced `UtilsModule` along with a `parseAuthorizationHeader` helper method.

## `1.0.0` - 04/09/2020

This is the first release our changelog records. Future updates will be logged in the following format:
Expand Down
7 changes: 7 additions & 0 deletions src/core/sdk-exceptions.ts
Original file line number Diff line number Diff line change
Expand Up @@ -49,3 +49,10 @@ export function createServiceError(...nestedErrors: any[]) {
nestedErrors,
);
}

export function createExpectedBearerStringError() {
return new MagicAdminSDKError(
ErrorCode.ExpectedBearerString,
'Expected argumenet to be a string in the `Bearer {token}` format.',
);
}
7 changes: 7 additions & 0 deletions src/core/sdk.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import { TokenModule } from '../modules/token';
import { UsersModule } from '../modules/users';
import { UtilsModule } from '../modules/utils';
import { MagicAdminSDKAdditionalConfiguration } from '../types';

export class MagicAdminSDK {
Expand All @@ -17,12 +18,18 @@ export class MagicAdminSDK {
*/
public readonly users: UsersModule;

/**
* Contains general utilities for Magic Admin SDK.
*/
public readonly utils: UtilsModule;

constructor(public readonly secretApiKey?: string, options?: MagicAdminSDKAdditionalConfiguration) {
const endpoint = options?.endpoint ?? 'https://api.magic.link';
this.apiBaseUrl = endpoint.replace(/\/+$/, '');

// Assign API Modules
this.token = new TokenModule(this);
this.users = new UsersModule(this);
this.utils = new UtilsModule(this);
}
}
2 changes: 1 addition & 1 deletion src/modules/users/index.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { BaseModule } from '../base-module';
import { createApiKeyMissingError } from '../../core/sdk-exceptions';
import { post, get } from '../../utils/rest';
import { generateIssuerFromPublicAddress, parsePublicAddressFromIssuer } from '../../utils/issuer';
import { generateIssuerFromPublicAddress } from '../../utils/issuer';
import { MagicUserMetadata } from '../../types';

export class UsersModule extends BaseModule {
Expand Down
15 changes: 15 additions & 0 deletions src/modules/utils/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
import { BaseModule } from '../base-module';
import { createExpectedBearerStringError } from '../../core/sdk-exceptions';

export class UtilsModule extends BaseModule {
/**
* Parse a raw DID Token from the given Authorization header.
*/
public parseAuthorizationHeader(header: string) {
if (!header.toLowerCase().startsWith('bearer ')) {
throw createExpectedBearerStringError();
}

return header.substring(7);
}
}
1 change: 1 addition & 0 deletions src/types/exception-types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,4 +6,5 @@ export enum ErrorCode {
ApiKeyMissing = 'ERROR_SECRET_API_KEY_MISSING',
MalformedTokenError = 'ERROR_MALFORMED_TOKEN',
ServiceError = 'SERVICE_ERROR',
ExpectedBearerString = 'EXPECTED_BEARER_STRING',
}
11 changes: 11 additions & 0 deletions test/spec/core/sdk-exceptions/error-factories.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import {
createFailedRecoveringProofError,
createApiKeyMissingError,
createServiceError,
createExpectedBearerStringError,
} from '../../../../src/core/sdk-exceptions';

function errorAssertions<T extends ExecutionContext<any>>(
Expand Down Expand Up @@ -73,3 +74,13 @@ test('#06: Creates `SERVICE_ERROR` error with non-empty `data` property', async
['hello', 'world'],
);
});

test('#07: Creates `EXPECTED_BEARER_STRING` error', async t => {
const error = createExpectedBearerStringError();
errorAssertions(
t,
error,
'EXPECTED_BEARER_STRING',
'Expected argumenet to be a string in the `Bearer {token}` format.',
);
});
2 changes: 2 additions & 0 deletions test/spec/core/sdk/constructor.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import { MagicAdminSDK } from '../../../../src/core/sdk';
import { API_FULL_URL, API_KEY } from '../../../lib/constants';
import { TokenModule } from '../../../../src/modules/token';
import { UsersModule } from '../../../../src/modules/users';
import { UtilsModule } from '../../../../src/modules/utils';

test.serial('#01: Initialize `MagicAdminSDK`', t => {
const magic = new MagicAdminSDK(API_KEY);
Expand All @@ -22,6 +23,7 @@ test.serial('#02: Initialize `MagicAdminSDK` with custom endpoint', t => {
t.is(magic.apiBaseUrl, 'https://example.com');
t.true(magic.token instanceof TokenModule);
t.true(magic.users instanceof UsersModule);
t.true(magic.utils instanceof UtilsModule);
});

test.serial('#03: Strips trailing slash(es) from custom endpoint argument', t => {
Expand Down
18 changes: 18 additions & 0 deletions test/spec/modules/utils/parseAuthorizationHeader.spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
import test from 'ava';
import { createMagicAdminSDK } from '../../../lib/factories';
import { VALID_DIDT } from '../../../lib/constants';
import { createExpectedBearerStringError, MagicAdminSDKError } from '../../../../src/core/sdk-exceptions';

test('#01: Successfully parses raw DIDT from `Bearer` authorization header', async t => {
const sdk = createMagicAdminSDK();
const result = sdk.utils.parseAuthorizationHeader(`Bearer ${VALID_DIDT}`);
t.deepEqual(result, VALID_DIDT);
});

test('#02: Raises error if header is in the wrong format', async t => {
const sdk = createMagicAdminSDK();
const expectedError = createExpectedBearerStringError();
const error: MagicAdminSDKError = t.throws(() => sdk.utils.parseAuthorizationHeader(`Ooops ${VALID_DIDT}`));
t.is(error.code, expectedError.code);
t.is(error.message, expectedError.message);
});

0 comments on commit 6affc13

Please sign in to comment.