diff --git a/package-lock.json b/package-lock.json index 7d6c2928..752ce903 100644 --- a/package-lock.json +++ b/package-lock.json @@ -41,7 +41,7 @@ "eslint-plugin-prettier": "^5.0.1", "expo": "^52.0.40", "faker": "^4.1.0", - "fetch-mock": "^7.3.9", + "fetch-mock": "^9.1.0", "husky": "^4.2.5", "jest": "^29.7.0", "jest-environment-jsdom": "^29.5.0", @@ -8373,25 +8373,6 @@ "@babel/plugin-syntax-flow": "^7.12.1" } }, - "node_modules/babel-polyfill": { - "version": "6.26.0", - "resolved": "https://registry.npmjs.org/babel-polyfill/-/babel-polyfill-6.26.0.tgz", - "integrity": "sha512-F2rZGQnAdaHWQ8YAoeRbukc7HS9QgdgeyJ0rQDd485v9opwuPvjpPFcOOT/WmkKTdgy9ESgSPXDcTNpzrGr6iQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "babel-runtime": "^6.26.0", - "core-js": "^2.5.0", - "regenerator-runtime": "^0.10.5" - } - }, - "node_modules/babel-polyfill/node_modules/regenerator-runtime": { - "version": "0.10.5", - "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.10.5.tgz", - "integrity": "sha512-02YopEIhAgiBHWeoTiA8aitHDt8z6w+rQqNuIftlM+ZtvSl/brTouaU7DW6GO/cHtvxJvS4Hwv2ibKdxIRi24w==", - "dev": true, - "license": "MIT" - }, "node_modules/babel-preset-current-node-syntax": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/babel-preset-current-node-syntax/-/babel-preset-current-node-syntax-1.1.0.tgz", @@ -8667,24 +8648,6 @@ "@babel/core": "^7.0.0" } }, - "node_modules/babel-runtime": { - "version": "6.26.0", - "resolved": "https://registry.npmjs.org/babel-runtime/-/babel-runtime-6.26.0.tgz", - "integrity": "sha512-ITKNuq2wKlW1fJg9sSW52eepoYgZBggvOAHC0u/CYu/qxQ9EVzThCgR69BnSXLHjy2f7SY5zaQ4yt7H9ZVxY2g==", - "dev": true, - "license": "MIT", - "dependencies": { - "core-js": "^2.4.0", - "regenerator-runtime": "^0.11.0" - } - }, - "node_modules/babel-runtime/node_modules/regenerator-runtime": { - "version": "0.11.1", - "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.11.1.tgz", - "integrity": "sha512-MguG95oij0fC3QV3URf4V2SDYGJhJnJGqvIIgdECeODCT98wSWDAJ94SSuVpYQUoTcGUIL6L4yNB7j1DFFHSBg==", - "dev": true, - "license": "MIT" - }, "node_modules/balanced-match": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", @@ -10303,13 +10266,16 @@ "license": "MIT" }, "node_modules/core-js": { - "version": "2.6.12", - "resolved": "https://registry.npmjs.org/core-js/-/core-js-2.6.12.tgz", - "integrity": "sha512-Kb2wC0fvsWfQrgk8HU5lW6U/Lcs8+9aaYcy4ZFc6DDlo4nZ7n70dEgE5rtR0oG6ufKDUnrwfWL1mXR5ljDatrQ==", - "deprecated": "core-js@<3.23.3 is no longer maintained and not recommended for usage due to the number of issues. Because of the V8 engine whims, feature detection in old core-js versions could cause a slowdown up to 100x even if nothing is polyfilled. Some versions have web compatibility issues. Please, upgrade your dependencies to the actual version of core-js.", + "version": "3.42.0", + "resolved": "https://registry.npmjs.org/core-js/-/core-js-3.42.0.tgz", + "integrity": "sha512-Sz4PP4ZA+Rq4II21qkNqOEDTDrCvcANId3xpIgB34NDkWc3UduWj2dqEtN9yZIq8Dk3HyPI33x9sqqU5C8sr0g==", "dev": true, "hasInstallScript": true, - "license": "MIT" + "license": "MIT", + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/core-js" + } }, "node_modules/core-js-compat": { "version": "3.41.0", @@ -13502,23 +13468,30 @@ } }, "node_modules/fetch-mock": { - "version": "7.7.3", - "resolved": "https://registry.npmjs.org/fetch-mock/-/fetch-mock-7.7.3.tgz", - "integrity": "sha512-I4OkK90JFQnjH8/n3HDtWxH/I6D1wrxoAM2ri+nb444jpuH3RTcgvXx2el+G20KO873W727/66T7QhOvFxNHPg==", + "version": "9.11.0", + "resolved": "https://registry.npmjs.org/fetch-mock/-/fetch-mock-9.11.0.tgz", + "integrity": "sha512-PG1XUv+x7iag5p/iNHD4/jdpxL9FtVSqRMUQhPab4hVDt80T1MH5ehzVrL2IdXO9Q2iBggArFvPqjUbHFuI58Q==", "dev": true, - "hasInstallScript": true, "license": "MIT", "dependencies": { - "babel-polyfill": "^6.26.0", - "core-js": "^2.6.9", + "@babel/core": "^7.0.0", + "@babel/runtime": "^7.0.0", + "core-js": "^3.0.0", + "debug": "^4.1.1", "glob-to-regexp": "^0.4.0", + "is-subset": "^0.1.1", "lodash.isequal": "^4.5.0", "path-to-regexp": "^2.2.1", + "querystring": "^0.2.0", "whatwg-url": "^6.5.0" }, "engines": { "node": ">=4.0.0" }, + "funding": { + "type": "charity", + "url": "https://www.justgiving.com/refugee-support-europe" + }, "peerDependencies": { "node-fetch": "*" }, @@ -16062,6 +16035,13 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/is-subset": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/is-subset/-/is-subset-0.1.1.tgz", + "integrity": "sha512-6Ybun0IkarhmEqxXCNw/C0bna6Zb/TkfUX9UbwJtK6ObwAVCxmAP308WWTHviM/zAqXk05cdhYsUsZeGQh99iw==", + "dev": true, + "license": "MIT" + }, "node_modules/is-symbol": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/is-symbol/-/is-symbol-1.1.1.tgz", @@ -21476,6 +21456,17 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/querystring": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/querystring/-/querystring-0.2.1.tgz", + "integrity": "sha512-wkvS7mL/JMugcup3/rMitHmd9ecIGd2lhFhK9N3UUQ450h66d1r3Y9nvXzQAW1Lq+wyx61k/1pfKS5KuKiyEbg==", + "deprecated": "The querystring API is considered Legacy. new code should use the URLSearchParams API instead.", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.4.x" + } + }, "node_modules/querystringify": { "version": "2.2.0", "resolved": "https://registry.npmjs.org/querystringify/-/querystringify-2.2.0.tgz", diff --git a/package.json b/package.json index 9c0e7a0f..b439b97b 100644 --- a/package.json +++ b/package.json @@ -101,7 +101,7 @@ "eslint-plugin-prettier": "^5.0.1", "expo": "^52.0.40", "faker": "^4.1.0", - "fetch-mock": "^7.3.9", + "fetch-mock": "^9.1.0", "husky": "^4.2.5", "jest": "^29.7.0", "jest-environment-jsdom": "^29.5.0", diff --git a/src/auth/__tests__/index.spec.js b/src/auth/__tests__/index.spec.js index 681a459b..c3bc56be 100644 --- a/src/auth/__tests__/index.spec.js +++ b/src/auth/__tests__/index.spec.js @@ -42,7 +42,7 @@ describe('auth', () => { jest.useFakeTimers().setSystemTime(new Date('2023-01-01')); }); - beforeEach(fetchMock.restore); + beforeEach(() => fetchMock.restore()); describe('constructor', () => { it('should build with domain', () => { @@ -57,7 +57,7 @@ describe('auth', () => { it('should fail without domain', () => { expect(() => new Auth({ clientId })).toThrowErrorMatchingSnapshot(); }); - + it('should accept custom headers', () => { const headers = { 'X-Custom-Header': 'custom-value' }; const auth = new Auth({ baseUrl, clientId, headers }); @@ -1061,22 +1061,22 @@ describe('auth', () => { }); describe('method-specific custom headers', () => { - it('should accept and use custom headers in passwordRealm that don\'t conflict with defaults', async () => { + it("should accept and use custom headers in passwordRealm that don't conflict with defaults", async () => { fetchMock.postOnce('https://samples.auth0.com/oauth/token', tokens); const customHeaders = { 'X-Custom-Header': 'custom-value' }; - + await auth.passwordRealm({ username: 'info@auth0.com', password: 'secret pass', realm: 'Username-Password-Authentication', - headers: customHeaders + headers: customHeaders, }); - + const [_, fetchOptions] = fetchMock.lastCall(); expect(fetchOptions.headers.get('X-Custom-Header')).toBe('custom-value'); }); - - it('should accept and use custom headers in userInfo that don\'t conflict with defaults', async () => { + + it("should accept and use custom headers in userInfo that don't conflict with defaults", async () => { const success = { status: 200, body: { sub: 'auth0|1029837475' }, @@ -1084,25 +1084,25 @@ describe('auth', () => { }; fetchMock.getOnce('https://samples.auth0.com/userinfo', success); const customHeaders = { 'X-Custom-Header': 'custom-value' }; - - await auth.userInfo({ + + await auth.userInfo({ token: 'an access token of a user', - headers: customHeaders + headers: customHeaders, }); - + const [_, fetchOptions] = fetchMock.lastCall(); expect(fetchOptions.headers.get('X-Custom-Header')).toBe('custom-value'); }); - - it('should accept and use custom headers in refreshToken that don\'t conflict with defaults', async () => { + + it("should accept and use custom headers in refreshToken that don't conflict with defaults", async () => { fetchMock.postOnce('https://samples.auth0.com/oauth/token', tokens); const customHeaders = { 'X-Custom-Header': 'custom-value' }; - + await auth.refreshToken({ refreshToken: 'a refresh token of a user', - headers: customHeaders + headers: customHeaders, }); - + const [_, fetchOptions] = fetchMock.lastCall(); expect(fetchOptions.headers.get('X-Custom-Header')).toBe('custom-value'); }); diff --git a/src/management/__tests__/users.spec.js b/src/management/__tests__/users.spec.js index cd67382f..40534b96 100644 --- a/src/management/__tests__/users.spec.js +++ b/src/management/__tests__/users.spec.js @@ -3,12 +3,12 @@ import fetchMock from 'fetch-mock'; describe('users', () => { const baseUrl = 'samples.auth0.com'; - const telemetry = {name: 'react-native-auth0', version: '1.0.0'}; + const telemetry = { name: 'react-native-auth0', version: '1.0.0' }; const token = 'a.token.from.the.user'; const unexpectedError = { status: 500, body: 'Internal Server Error....', - headers: {'Content-Type': 'text/plain'}, + headers: { 'Content-Type': 'text/plain' }, }; const auth0Error = { status: 403, @@ -18,25 +18,25 @@ describe('users', () => { message: 'User to be acted on does not match subject in bearer token.', statusCode: 403, }, - headers: {'Content-Type': 'application/json'}, + headers: { 'Content-Type': 'application/json' }, }; - const users = new Users({baseUrl, telemetry, token}); + const users = new Users({ baseUrl, telemetry, token }); - beforeEach(fetchMock.restore); + beforeEach(() => fetchMock.restore()); describe('constructor', () => { it('should build with domain', () => { - const users = new Users({baseUrl, token}); + const users = new Users({ baseUrl, token }); expect(users.client.bearer).toContain(token); }); it('should fail without token', () => { - expect(() => new Users({baseUrl})).toThrowErrorMatchingSnapshot(); + expect(() => new Users({ baseUrl })).toThrowErrorMatchingSnapshot(); }); it('should fail without domain', () => { - expect(() => new Users({token})).toThrowErrorMatchingSnapshot(); + expect(() => new Users({ token })).toThrowErrorMatchingSnapshot(); }); }); @@ -46,83 +46,83 @@ describe('users', () => { it('should send correct payload', async () => { fetchMock.getOnce( `https://samples.auth0.com/api/v2/users/${encodeURIComponent(userId)}`, - user, + user ); expect.assertions(1); - await users.getUser({id: userId}); + await users.getUser({ id: userId }); expect(fetchMock.lastCall()).toMatchSnapshot(); }); it('should return successful response', async () => { fetchMock.getOnce( `https://samples.auth0.com/api/v2/users/${encodeURIComponent(userId)}`, - user, + user ); expect.assertions(1); - await expect(users.getUser({id: userId})).resolves.toMatchSnapshot(); + await expect(users.getUser({ id: userId })).resolves.toMatchSnapshot(); }); it('should handle oauth error', async () => { fetchMock.getOnce( `https://samples.auth0.com/api/v2/users/${encodeURIComponent(userId)}`, - auth0Error, + auth0Error ); expect.assertions(1); - await expect(users.getUser({id: userId})).rejects.toMatchSnapshot(); + await expect(users.getUser({ id: userId })).rejects.toMatchSnapshot(); }); it('should handle unexpected error', async () => { fetchMock.getOnce( `https://samples.auth0.com/api/v2/users/${encodeURIComponent(userId)}`, - unexpectedError, + unexpectedError ); expect.assertions(1); - await expect(users.getUser({id: userId})).rejects.toMatchSnapshot(); + await expect(users.getUser({ id: userId })).rejects.toMatchSnapshot(); }); }); describe('PATCH user', () => { - const metadata = {first_name: 'Mike', lastName: 'Doe'}; + const metadata = { first_name: 'Mike', lastName: 'Doe' }; it('should send correct payload', async () => { fetchMock.patchOnce( `https://samples.auth0.com/api/v2/users/${encodeURIComponent(userId)}`, - user, + user ); expect.assertions(1); - await users.patchUser({id: userId, metadata}); + await users.patchUser({ id: userId, metadata }); expect(fetchMock.lastCall()).toMatchSnapshot(); }); it('should return successful response', async () => { fetchMock.patchOnce( `https://samples.auth0.com/api/v2/users/${encodeURIComponent(userId)}`, - user, + user ); expect.assertions(1); await expect( - users.patchUser({id: userId, metadata}), + users.patchUser({ id: userId, metadata }) ).resolves.toMatchSnapshot(); }); it('should handle oauth error', async () => { fetchMock.patchOnce( `https://samples.auth0.com/api/v2/users/${encodeURIComponent(userId)}`, - auth0Error, + auth0Error ); expect.assertions(1); await expect( - users.patchUser({id: userId, metadata}), + users.patchUser({ id: userId, metadata }) ).rejects.toMatchSnapshot(); }); it('should handle unexpected error', async () => { fetchMock.patchOnce( `https://samples.auth0.com/api/v2/users/${encodeURIComponent(userId)}`, - unexpectedError, + unexpectedError ); expect.assertions(1); await expect( - users.patchUser({id: userId, metadata}), + users.patchUser({ id: userId, metadata }) ).rejects.toMatchSnapshot(); }); }); diff --git a/src/networking/__tests__/index.spec.js b/src/networking/__tests__/index.spec.js index c3041cc1..5fd85fa4 100644 --- a/src/networking/__tests__/index.spec.js +++ b/src/networking/__tests__/index.spec.js @@ -1,7 +1,7 @@ import Client from '..'; -import {defaults} from '../telemetry'; +import { defaults } from '../telemetry'; import fetchMock from 'fetch-mock'; -import {TimeoutError} from '../../utils/fetchWithTimeout'; +import { TimeoutError } from '../../utils/fetchWithTimeout'; jest.useFakeTimers(); @@ -11,26 +11,26 @@ describe('client', () => { describe('constructor', () => { it('should accept only baseUrl', () => { - const client = new Client({baseUrl}); + const client = new Client({ baseUrl }); expect(client.baseUrl).toEqual(baseUrl); expect(client.telemetry).toMatchObject(defaults); }); it('should accept only domain', () => { - const client = new Client({baseUrl: domain}); + const client = new Client({ baseUrl: domain }); expect(client.baseUrl).toEqual(baseUrl); expect(client.telemetry).toMatchObject(defaults); }); it('should accept only http baseUrl', () => { - const client = new Client({baseUrl: 'http://insecure.com'}); + const client = new Client({ baseUrl: 'http://insecure.com' }); expect(client.baseUrl).toEqual('http://insecure.com'); expect(client.telemetry).toMatchObject(defaults); }); it('should allow to customize telemetry', () => { - const custom = {name: 'react-native-lock', version: '1.0.0-rc.1'}; - const client = new Client({baseUrl, telemetry: custom}); + const custom = { name: 'react-native-lock', version: '1.0.0-rc.1' }; + const client = new Client({ baseUrl, telemetry: custom }); expect(client.telemetry).toMatchObject({ ...custom, env: { @@ -41,13 +41,13 @@ describe('client', () => { it('should allow to specify a bearer token', () => { const token = 'a.bearer.token'; - const client = new Client({baseUrl, token}); + const client = new Client({ baseUrl, token }); expect(client.bearer).toEqual('Bearer a.bearer.token'); }); it('should accept global headers', () => { const headers = { 'X-Custom-Header': 'custom-value' }; - const client = new Client({baseUrl, headers}); + const client = new Client({ baseUrl, headers }); expect(client.globalHeaders).toEqual(headers); }); @@ -59,11 +59,11 @@ describe('client', () => { describe('requests', () => { const client = new Client({ baseUrl, - telemetry: {name: 'react-native-auth0', version: '1.0.0'}, + telemetry: { name: 'react-native-auth0', version: '1.0.0' }, token: 'a.bearer.token', }); - beforeEach(fetchMock.restore); + beforeEach(() => fetchMock.restore()); describe('POST json', () => { const body = { @@ -100,7 +100,7 @@ describe('client', () => { }); it('should handle no response', async () => { - fetchMock.postOnce('https://samples.auth0.com/method', {status: 201}); + fetchMock.postOnce('https://samples.auth0.com/method', { status: 201 }); expect.assertions(1); await expect(client.post('/method', body)).resolves.toMatchSnapshot(); }); @@ -182,7 +182,7 @@ describe('client', () => { it('should build proper request with query', async () => { fetchMock.getOnce( 'https://samples.auth0.com/method?string=value&number=10', - response, + response ); expect.assertions(1); await client.get('/method', query); @@ -199,7 +199,7 @@ describe('client', () => { it('should return json on success', async () => { fetchMock.getOnce( 'https://samples.auth0.com/method?string=value&number=10', - response, + response ); expect.assertions(1); await expect(client.get('/method', query)).resolves.toMatchSnapshot(); @@ -208,7 +208,7 @@ describe('client', () => { it('should handle no response', async () => { fetchMock.getOnce( 'https://samples.auth0.com/method?string=value&number=10', - {status: 201}, + { status: 201 } ); expect.assertions(1); await expect(client.get('/method', query)).resolves.toMatchSnapshot(); @@ -217,7 +217,7 @@ describe('client', () => { it('should handle request error', async () => { fetchMock.getOnce( 'https://samples.auth0.com/method?string=value&number=10', - {throws: new Error('pawned!')}, + { throws: new Error('pawned!') } ); expect.assertions(1); await expect(client.get('/method', query)).rejects.toMatchSnapshot(); @@ -229,9 +229,9 @@ describe('client', () => { const globalHeaders = { 'X-Global-Header': 'global-value' }; const client = new Client({ baseUrl, - telemetry: {name: 'react-native-auth0', version: '1.0.0'}, + telemetry: { name: 'react-native-auth0', version: '1.0.0' }, token: 'a.bearer.token', - headers: globalHeaders + headers: globalHeaders, }); const response = { @@ -243,7 +243,7 @@ describe('client', () => { }, }; - beforeEach(fetchMock.restore); + beforeEach(() => fetchMock.restore()); it('should include global headers in request', async () => { fetchMock.postOnce('https://samples.auth0.com/method', response); @@ -253,22 +253,24 @@ describe('client', () => { expect(fetchOptions.headers.get('X-Global-Header')).toBe('global-value'); }); - it('should allow request-specific headers that don\'t conflict with default headers', async () => { + it("should allow request-specific headers that don't conflict with default headers", async () => { fetchMock.postOnce('https://samples.auth0.com/method', response); expect.assertions(1); - const requestHeaders = { - 'X-Request-Header': 'request-value' + const requestHeaders = { + 'X-Request-Header': 'request-value', }; await client.post('/method', {}, requestHeaders); const [_, fetchOptions] = fetchMock.lastCall(); - expect(fetchOptions.headers.get('X-Request-Header')).toBe('request-value'); + expect(fetchOptions.headers.get('X-Request-Header')).toBe( + 'request-value' + ); }); - + it('should not override default headers with custom headers', async () => { fetchMock.postOnce('https://samples.auth0.com/method', response); expect.assertions(1); - const requestHeaders = { - 'Content-Type': 'text/plain' // This should not override the default + const requestHeaders = { + 'Content-Type': 'text/plain', // This should not override the default }; await client.post('/method', {}, requestHeaders); const [_, fetchOptions] = fetchMock.lastCall(); @@ -279,7 +281,7 @@ describe('client', () => { describe('url', () => { const client = new Client({ baseUrl, - telemetry: {name: 'react-native-auth0', version: '1.0.0'}, + telemetry: { name: 'react-native-auth0', version: '1.0.0' }, token: 'a.bearer.token', }); @@ -293,7 +295,7 @@ describe('client', () => { it('should build url with query', () => { expect( - client.url('/authorize', {client_id: 'A_CLIENT_ID'}, true), + client.url('/authorize', { client_id: 'A_CLIENT_ID' }, true) ).toMatchSnapshot(); }); }); @@ -301,7 +303,7 @@ describe('client', () => { describe('timeout', () => { const client = new Client({ baseUrl, - telemetry: {name: 'react-native-auth0', version: '1.0.0'}, + telemetry: { name: 'react-native-auth0', version: '1.0.0' }, token: 'a.bearer.token', timeout: 2, }); @@ -322,7 +324,7 @@ describe('client', () => { fetchMock.restore(); fetchMock.mock('https://samples.auth0.com/method', () => { - return new Promise(resolve => { + return new Promise((resolve) => { responseTimerId = setTimeout(() => { resolve(response); }, 2000);