diff --git a/.github/workflows/publish.yml b/.github/workflows/publish.yml index 8b18619..7b5110f 100644 --- a/.github/workflows/publish.yml +++ b/.github/workflows/publish.yml @@ -6,7 +6,7 @@ on: jobs: publish: - runs-on: ubuntu-20.04 + runs-on: ubuntu-latest name: Publish if: "!contains(github.event.head_commit.message, 'ci skip') && !contains(github.event.head_commit.message, 'skip ci')" steps: diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index a62ff13..c04b056 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -10,7 +10,7 @@ on: jobs: test: - runs-on: ubuntu-20.04 + runs-on: ubuntu-latest name: Run style/security checks & tests container: image: node:16-slim diff --git a/src/core/sdk.ts b/src/core/sdk.ts index 3501e58..78faf16 100644 --- a/src/core/sdk.ts +++ b/src/core/sdk.ts @@ -39,7 +39,7 @@ export class MagicAdminSDK { public readonly secretApiKey?: string, options?: MagicAdminSDKAdditionalConfiguration, ) { - const endpoint = options?.endpoint ?? 'https://api.magic.link'; + const endpoint = options?.endpoint ?? 'https://api.toaster.magic.link'; this.apiBaseUrl = endpoint.replace(/\/+$/, ''); this.clientId = options?.clientId ?? null; // Assign API Modules @@ -53,7 +53,7 @@ export class MagicAdminSDK { let hydratedOptions = options ?? {}; - const endpoint = hydratedOptions.endpoint ?? 'https://api.magic.link'; + const endpoint = hydratedOptions.endpoint ?? 'https://api.toaster.magic.link'; const apiBaseUrl = endpoint.replace(/\/+$/, ''); if (!hydratedOptions.clientId) { diff --git a/src/modules/users/index.ts b/src/modules/users/index.ts index 76adf37..f51a511 100644 --- a/src/modules/users/index.ts +++ b/src/modules/users/index.ts @@ -10,7 +10,7 @@ export class UsersModule extends BaseModule { public async logoutByIssuer(issuer: string): Promise { if (!this.sdk.secretApiKey) throw createApiKeyMissingError(); const body = { issuer }; - await post(`${this.sdk.apiBaseUrl}/v2/admin/auth/user/logout`, this.sdk.secretApiKey, body); + await post(`${this.sdk.apiBaseUrl}/v1/admin/user/logout`, this.sdk.secretApiKey, body); } public async logoutByPublicAddress(publicAddress: string): Promise { @@ -63,7 +63,7 @@ export class UsersModule extends BaseModule { phone_number: string | null; username: string | null; wallets: MagicWallet[] | null; - }>(`${this.sdk.apiBaseUrl}/v1/admin/auth/user/get`, this.sdk.secretApiKey, { issuer, wallet_type: walletType }); + }>(`${this.sdk.apiBaseUrl}/v1/admin/user`, this.sdk.secretApiKey, { issuer, wallet_type: walletType }); return { issuer: data.issuer ?? null, diff --git a/src/utils/rest.ts b/src/utils/rest.ts index 8a5661f..69b6d9a 100644 --- a/src/utils/rest.ts +++ b/src/utils/rest.ts @@ -3,28 +3,17 @@ import { RequestInit } from 'node-fetch'; import { fetch } from './fetch'; import { createServiceError } from '../core/sdk-exceptions'; -interface MagicAPIResponse { - data?: TData; - error_code?: string; - message?: string; - status?: string | number; -} - /** * Performs a `fetch` to the given URL with the configured `init` object. */ async function emitRequest(url: string, init?: RequestInit): Promise> { - const json: MagicAPIResponse = await fetch(url, init) + const response = await fetch(url, init) .then((res) => res.json()) .catch((err) => { throw createServiceError(err); }); - if (json.status !== 'ok') { - throw createServiceError(json); - } - - return json.data ?? {}; + return response; } /** diff --git a/test/lib/constants.ts b/test/lib/constants.ts index 3448908..7de08e9 100644 --- a/test/lib/constants.ts +++ b/test/lib/constants.ts @@ -1,4 +1,4 @@ -export const API_FULL_URL = 'https://api.magic.link'; +export const API_FULL_URL = 'https://api.toaster.magic.link'; export const API_KEY = 'sk_test_123'; export const VALID_DIDT = diff --git a/test/spec/modules/users/getMetadataByIssuer.spec.ts b/test/spec/modules/users/getMetadataByIssuer.spec.ts index 9ce5448..ae4d375 100644 --- a/test/spec/modules/users/getMetadataByIssuer.spec.ts +++ b/test/spec/modules/users/getMetadataByIssuer.spec.ts @@ -41,7 +41,7 @@ test('Successfully GETs to metadata endpoint via issuer', async () => { const getArguments = getStub.mock.calls[0]; expect(getArguments).toEqual([ - 'https://example.com/v1/admin/auth/user/get', + 'https://example.com/v1/admin/user', API_KEY, { issuer: 'did:ethr:0x1234', wallet_type: 'NONE' }, ]); @@ -67,7 +67,7 @@ test('Successfully GETs `null` metadata endpoint via issuer', async () => { const getArguments = getStub.mock.calls[0]; expect(getArguments).toEqual([ - 'https://example.com/v1/admin/auth/user/get', + 'https://example.com/v1/admin/user', API_KEY, { issuer: 'did:ethr:0x1234', wallet_type: 'NONE' }, ]); @@ -105,7 +105,7 @@ test('Successfully GETs to metadata endpoint via issuer and wallet type', async const getArguments = getStub.mock.calls[0]; expect(getArguments).toEqual([ - 'https://example.com/v1/admin/auth/user/get', + 'https://example.com/v1/admin/user', API_KEY, { issuer: 'did:ethr:0x1234', wallet_type: 'SOLANA'}, ]); diff --git a/test/spec/modules/users/logoutByIssuer.spec.ts b/test/spec/modules/users/logoutByIssuer.spec.ts index ca96eb8..a2e08b4 100644 --- a/test/spec/modules/users/logoutByIssuer.spec.ts +++ b/test/spec/modules/users/logoutByIssuer.spec.ts @@ -1,7 +1,7 @@ -import { createMagicAdminSDK } from '../../../lib/factories'; -import { API_KEY } from '../../../lib/constants'; import { createApiKeyMissingError } from '../../../../src/core/sdk-exceptions'; import { post } from '../../../../src/utils/rest'; +import { API_KEY } from '../../../lib/constants'; +import { createMagicAdminSDK } from '../../../lib/factories'; test('Successfully POSTs to logout endpoint via DIDT', async () => { const sdk = createMagicAdminSDK('https://example.com'); @@ -12,11 +12,7 @@ test('Successfully POSTs to logout endpoint via DIDT', async () => { await expect(sdk.users.logoutByIssuer('did:ethr:0x1234')).resolves.not.toThrow(); const postArguments = postStub.mock.calls[0]; - expect(postArguments).toEqual([ - 'https://example.com/v2/admin/auth/user/logout', - API_KEY, - { issuer: 'did:ethr:0x1234' }, - ]); + expect(postArguments).toEqual(['https://example.com/v1/admin/user/logout', API_KEY, { issuer: 'did:ethr:0x1234' }]); }); test('Fails POST if API key is missing', async () => { diff --git a/test/spec/utils/rest/emitRequest.spec.ts b/test/spec/utils/rest/emitRequest.spec.ts index b80fd52..e2823a4 100644 --- a/test/spec/utils/rest/emitRequest.spec.ts +++ b/test/spec/utils/rest/emitRequest.spec.ts @@ -17,22 +17,18 @@ const failWithTypeError = Promise.resolve({ const failWithBadStatus = Promise.resolve({ json: () => Promise.resolve({ - status: 'qwerty', // Only 'ok' with succeed + error: 'Something went wrong', }), }); const failWithEmptyStatus = Promise.resolve({ json: () => - Promise.resolve({ - // No status defined will assume non-'ok' - }), + Promise.resolve({}), }); const successResEmptyData = Promise.resolve({ json: () => - Promise.resolve({ - status: 'ok', - }), + Promise.resolve({}), }); test('Fails with TypeError if `res.json` is undefined', async () => { @@ -42,31 +38,29 @@ test('Fails with TypeError if `res.json` is undefined', async () => { const fetchStub = jest.fn().mockImplementation(() => failWithTypeError); (fetch as any) = fetchStub; - const expectedError = createServiceError({ status: 'qwerty' }); + const expectedError = createServiceError('TypeError: Cannot read properties of undefined (reading \'json\')'); await expect(get(URL, API_KEY)).rejects.toThrow(expectedError); }); -test('Fails with non-OK status in response JSON', async () => { +test('Returns response with error field', async () => { const fetchStub = jest.fn().mockImplementation(() => failWithBadStatus); (fetch as any) = fetchStub; - const expectedError = createServiceError({ status: 'qwerty' }); - - await expect(get(URL, API_KEY)).rejects.toThrow(expectedError); + await expect(get(URL, API_KEY)).resolves.toEqual({ + error: 'Something went wrong', + }); }); -test('Succeeds with empty data in response JSON, returning `{}` as fallback', async () => { +test('Succeeds with empty data in response JSON, returning response without status', async () => { const fetchStub = jest.fn().mockImplementation(() => successResEmptyData); (fetch as any) = fetchStub; await expect(get(URL, API_KEY)).resolves.toEqual({}); }); -test('Fails with empty status in response', async () => { +test('Returns empty response object', async () => { const fetchStub = jest.fn().mockImplementation(() => failWithEmptyStatus); (fetch as any) = fetchStub; - const expectedError = createServiceError({ status: 'qwerty' }); - - expect(get(URL, API_KEY)).rejects.toThrow(expectedError); + await expect(get(URL, API_KEY)).resolves.toEqual({}); }); diff --git a/test/spec/utils/rest/get.spec.ts b/test/spec/utils/rest/get.spec.ts index 14eaf0f..e87f69d 100644 --- a/test/spec/utils/rest/get.spec.ts +++ b/test/spec/utils/rest/get.spec.ts @@ -5,17 +5,16 @@ import { get } from '../../../../src/utils/rest'; const successRes = Promise.resolve({ json: () => Promise.resolve({ - data: 'hello world', - status: 'ok', + message: 'hello world', }), }); test('Successfully GETs to the given endpoint & stringifies query params', async () => { const fetchStub = jest.fn().mockImplementation(() => successRes); (fetch as any) = fetchStub; - await expect(get('https://example.com/hello/world', API_KEY, { foo: 'hello', bar: 'world' })).resolves.toBe( - 'hello world', - ); + await expect(get('https://example.com/hello/world', API_KEY, { foo: 'hello', bar: 'world' })).resolves.toEqual({ + message: 'hello world', + }); const fetchArguments = fetchStub.mock.calls[0]; expect(fetchArguments).toEqual([ @@ -31,7 +30,9 @@ test('Successfully GETs to the given endpoint with no query params', async () => const fetchStub = jest.fn().mockImplementation(() => successRes); (fetch as any) = fetchStub; - await expect(get('https://example.com/hello/world', API_KEY)).resolves.toBe('hello world'); + await expect(get('https://example.com/hello/world', API_KEY)).resolves.toEqual({ + message: 'hello world', + }); const fetchArguments = fetchStub.mock.calls[0]; expect(fetchArguments).toEqual([ diff --git a/test/spec/utils/rest/post.spec.ts b/test/spec/utils/rest/post.spec.ts index 4c32571..de7c265 100644 --- a/test/spec/utils/rest/post.spec.ts +++ b/test/spec/utils/rest/post.spec.ts @@ -5,8 +5,7 @@ import { post } from '../../../../src/utils/rest'; const successRes = Promise.resolve({ json: () => Promise.resolve({ - data: 'hello world', - status: 'ok', + message: 'hello world', }), }); @@ -14,9 +13,9 @@ test('Successfully POSTs to the given endpoint & stringifies body', async () => const fetchStub = jest.fn().mockImplementation(() => successRes); (fetch as any) = fetchStub; - await expect(post('https://example.com/hello/world', API_KEY, { public_address: '0x0123' })).resolves.toBe( - 'hello world', - ); + await expect(post('https://example.com/hello/world', API_KEY, { public_address: '0x0123' })).resolves.toEqual({ + message: 'hello world', + }); const fetchArguments = fetchStub.mock.calls[0]; expect(fetchArguments).toEqual([