diff --git a/app/components/modal/monitor/pages/initial/parent.tsx b/app/components/modal/monitor/pages/initial/parent.tsx
index ea2bff9a..4dd7b4f5 100644
--- a/app/components/modal/monitor/pages/initial/parent.tsx
+++ b/app/components/modal/monitor/pages/initial/parent.tsx
@@ -58,6 +58,10 @@ const MonitorParentSelect = ({
key={monitor.monitorId}
onClick={() => onSelect(monitor.monitorId)}
>
+
{monitor.name}
))}
diff --git a/app/components/modal/settings/authentication/configure.tsx b/app/components/modal/settings/authentication/configure.tsx
index 8d32489a..95983665 100644
--- a/app/components/modal/settings/authentication/configure.tsx
+++ b/app/components/modal/settings/authentication/configure.tsx
@@ -24,7 +24,12 @@ const SettingsAuthenticationConfigureModal = ({
const [values, setValues] = useState({
clientId: provider?.clientId || '',
clientSecret: provider?.clientSecret || '',
+ authUrl: provider?.data?.authUrl || '',
+ tokenUrl: provider?.data?.tokenUrl || '',
+ userInfoUrl: provider?.data?.userInfoUrl || '',
+ name: provider?.data?.name || '',
});
+
const currentUrl = useCurrentUrl();
const { addProvider } = useAuthenticationContext();
@@ -35,7 +40,12 @@ const SettingsAuthenticationConfigureModal = ({
clientId: values.clientId,
clientSecret: values.clientSecret,
enabled: true,
- data: {},
+ data: {
+ tokenUrl: values.tokenUrl,
+ name: values.name,
+ authUrl: values.authUrl,
+ userInfoUrl: values.userInfoUrl,
+ },
};
const provider = await createPostRequest(
@@ -70,6 +80,49 @@ const SettingsAuthenticationConfigureModal = ({
}
onClose={closeModal}
>
+ {integration.id === 'custom' && (
+ <>
+ ) =>
+ setValues((prev) => ({ ...prev, name: e.target.value }))
+ }
+ isRequired
+ />
+
+ ) =>
+ setValues((prev) => ({ ...prev, authUrl: e.target.value }))
+ }
+ isRequired
+ />
+
+ ) =>
+ setValues((prev) => ({ ...prev, tokenUrl: e.target.value }))
+ }
+ isRequired
+ />
+
+ ) =>
+ setValues((prev) => ({ ...prev, userInfoUrl: e.target.value }))
+ }
+ isRequired
+ />
+ >
+ )}
=10"
}
},
- "node_modules/fs.realpath": {
- "version": "1.0.0",
- "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz",
- "integrity": "sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==",
- "license": "ISC"
- },
"node_modules/fsevents": {
"version": "2.3.3",
"resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz",
@@ -8483,17 +8462,6 @@
"node": ">=8"
}
},
- "node_modules/inflight": {
- "version": "1.0.6",
- "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz",
- "integrity": "sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==",
- "deprecated": "This module is not supported, and leaks memory. Do not use it. Check out lru-cache if you want a good and tested way to coalesce async requests by a key value, which is much more comprehensive and powerful.",
- "license": "ISC",
- "dependencies": {
- "once": "^1.3.0",
- "wrappy": "1"
- }
- },
"node_modules/inherits": {
"version": "2.0.4",
"resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz",
@@ -9227,6 +9195,7 @@
"version": "3.1.0",
"resolved": "https://registry.npmjs.org/jsesc/-/jsesc-3.1.0.tgz",
"integrity": "sha512-/sM3dO2FOzXjKQhJuo0Q173wf2KOo8t4I8vHy6lF9poUp7bKT0/NHE8fPX23PwfhnykfqnC2xRxOnVw5XuGIaA==",
+ "dev": true,
"license": "MIT",
"bin": {
"jsesc": "bin/jsesc"
@@ -10079,12 +10048,6 @@
"dev": true,
"license": "MIT"
},
- "node_modules/lossless-json": {
- "version": "4.1.1",
- "resolved": "https://registry.npmjs.org/lossless-json/-/lossless-json-4.1.1.tgz",
- "integrity": "sha512-HusN80C0ohtT9kOHQH7EuUaqzRQsnekpa+2ot8OzvW0iC08dq/YtM/7uKwwajldQsCrHyC8q9fz3t3L+TmDltA==",
- "license": "MIT"
- },
"node_modules/lru-cache": {
"version": "5.1.1",
"resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-5.1.1.tgz",
@@ -10287,6 +10250,7 @@
"version": "3.1.2",
"resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz",
"integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==",
+ "dev": true,
"license": "ISC",
"dependencies": {
"brace-expansion": "^1.1.7"
@@ -10494,17 +10458,6 @@
"webidl-conversions": "^3.0.0"
}
},
- "node_modules/node-gyp-build": {
- "version": "4.8.4",
- "resolved": "https://registry.npmjs.org/node-gyp-build/-/node-gyp-build-4.8.4.tgz",
- "integrity": "sha512-LA4ZjwlnUblHVgq0oBF3Jl/6h/Nvs5fzBLwdEF4nuxnFdsfajde4WfxtJr3CaiH+F6ewcIB/q4jQ4UzPyid+CQ==",
- "license": "MIT",
- "bin": {
- "node-gyp-build": "bin.js",
- "node-gyp-build-optional": "optional.js",
- "node-gyp-build-test": "build-test.js"
- }
- },
"node_modules/node-mocks-http": {
"version": "1.17.2",
"resolved": "https://registry.npmjs.org/node-mocks-http/-/node-mocks-http-1.17.2.tgz",
@@ -10978,15 +10931,6 @@
"node": ">=8"
}
},
- "node_modules/path-is-absolute": {
- "version": "1.0.1",
- "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz",
- "integrity": "sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==",
- "license": "MIT",
- "engines": {
- "node": ">=0.10.0"
- }
- },
"node_modules/path-key": {
"version": "3.1.1",
"resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz",
@@ -12588,12 +12532,6 @@
"node": ">= 10.x"
}
},
- "node_modules/sprintf-js": {
- "version": "1.0.3",
- "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz",
- "integrity": "sha512-D9cPgkvLlV3t3IzL0D0YLvGA9Ahk4PcvVwUbN0dSGr1aP0Nrt4AEnTUbuGvquEC0mA64Gqt1fzirlRs5ibXx8g==",
- "license": "BSD-3-Clause"
- },
"node_modules/sshpk": {
"version": "1.18.0",
"resolved": "https://registry.npmjs.org/sshpk/-/sshpk-1.18.0.tgz",
@@ -13127,54 +13065,6 @@
"tree-kill": "cli.js"
}
},
- "node_modules/tree-sitter": {
- "version": "0.21.1",
- "resolved": "https://registry.npmjs.org/tree-sitter/-/tree-sitter-0.21.1.tgz",
- "integrity": "sha512-7dxoA6kYvtgWw80265MyqJlkRl4yawIjO7S5MigytjELkX43fV2WsAXzsNfO7sBpPPCF5Gp0+XzHk0DwLCq3xQ==",
- "hasInstallScript": true,
- "license": "MIT",
- "dependencies": {
- "node-addon-api": "^8.0.0",
- "node-gyp-build": "^4.8.0"
- }
- },
- "node_modules/tree-sitter-bash": {
- "version": "0.23.3",
- "resolved": "https://registry.npmjs.org/tree-sitter-bash/-/tree-sitter-bash-0.23.3.tgz",
- "integrity": "sha512-36cg/GQ2YmIbeiBeqeuh4fBJ6i4kgVouDaqTxqih5ysPag+zHufyIaxMOFeM8CeplwAK/Luj1o5XHqgdAfoCZg==",
- "hasInstallScript": true,
- "license": "MIT",
- "dependencies": {
- "node-addon-api": "^8.2.1",
- "node-gyp-build": "^4.8.2"
- },
- "peerDependencies": {
- "tree-sitter": "^0.21.1"
- },
- "peerDependenciesMeta": {
- "tree-sitter": {
- "optional": true
- }
- }
- },
- "node_modules/tree-sitter-bash/node_modules/node-addon-api": {
- "version": "8.4.0",
- "resolved": "https://registry.npmjs.org/node-addon-api/-/node-addon-api-8.4.0.tgz",
- "integrity": "sha512-D9DI/gXHvVmjHS08SVch0Em8G5S1P+QWtU31appcKT/8wFSPRcdHadIFSAntdMMVM5zz+/DL+bL/gz3UDppqtg==",
- "license": "MIT",
- "engines": {
- "node": "^18 || ^20 || >= 21"
- }
- },
- "node_modules/tree-sitter/node_modules/node-addon-api": {
- "version": "8.4.0",
- "resolved": "https://registry.npmjs.org/node-addon-api/-/node-addon-api-8.4.0.tgz",
- "integrity": "sha512-D9DI/gXHvVmjHS08SVch0Em8G5S1P+QWtU31appcKT/8wFSPRcdHadIFSAntdMMVM5zz+/DL+bL/gz3UDppqtg==",
- "license": "MIT",
- "engines": {
- "node": "^18 || ^20 || >= 21"
- }
- },
"node_modules/triple-beam": {
"version": "1.4.1",
"resolved": "https://registry.npmjs.org/triple-beam/-/triple-beam-1.4.1.tgz",
@@ -13875,12 +13765,6 @@
"node": ">=0.10.0"
}
},
- "node_modules/web-tree-sitter": {
- "version": "0.24.7",
- "resolved": "https://registry.npmjs.org/web-tree-sitter/-/web-tree-sitter-0.24.7.tgz",
- "integrity": "sha512-CdC/TqVFbXqR+C51v38hv6wOPatKEUGxa39scAeFSm98wIhZxAYonhRQPSMmfZ2w7JDI0zQDdzdmgtNk06/krQ==",
- "license": "MIT"
- },
"node_modules/which": {
"version": "2.0.2",
"resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz",
@@ -14124,50 +14008,6 @@
"node": ">= 14.6"
}
},
- "node_modules/yamljs": {
- "version": "0.3.0",
- "resolved": "https://registry.npmjs.org/yamljs/-/yamljs-0.3.0.tgz",
- "integrity": "sha512-C/FsVVhht4iPQYXOInoxUM/1ELSf9EsgKH34FofQOp6hwCPrW4vG4w5++TED3xRUo8gD7l0P1J1dLlDYzODsTQ==",
- "license": "MIT",
- "dependencies": {
- "argparse": "^1.0.7",
- "glob": "^7.0.5"
- },
- "bin": {
- "json2yaml": "bin/json2yaml",
- "yaml2json": "bin/yaml2json"
- }
- },
- "node_modules/yamljs/node_modules/argparse": {
- "version": "1.0.10",
- "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz",
- "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==",
- "license": "MIT",
- "dependencies": {
- "sprintf-js": "~1.0.2"
- }
- },
- "node_modules/yamljs/node_modules/glob": {
- "version": "7.2.3",
- "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz",
- "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==",
- "deprecated": "Glob versions prior to v9 are no longer supported",
- "license": "ISC",
- "dependencies": {
- "fs.realpath": "^1.0.0",
- "inflight": "^1.0.4",
- "inherits": "2",
- "minimatch": "^3.1.1",
- "once": "^1.3.0",
- "path-is-absolute": "^1.0.0"
- },
- "engines": {
- "node": "*"
- },
- "funding": {
- "url": "https://github.com/sponsors/isaacs"
- }
- },
"node_modules/yargs": {
"version": "17.7.2",
"resolved": "https://registry.npmjs.org/yargs/-/yargs-17.7.2.tgz",
diff --git a/package.json b/package.json
index 8ed274e5..fb31b0f8 100644
--- a/package.json
+++ b/package.json
@@ -1,6 +1,6 @@
{
"name": "lunalytics",
- "version": "0.10.13",
+ "version": "0.10.14",
"description": "Open source Node.js server/website monitoring tool",
"private": true,
"author": "KSJaay ",
@@ -55,7 +55,6 @@
"cors": "2.8.5",
"cron": "4.3.1",
"cross-env": "7.0.3",
- "curlconverter": "4.12.0",
"dayjs": "1.11.13",
"express": "4.21.2",
"i18next": "25.3.2",
diff --git a/server/database/queries/provider.js b/server/database/queries/provider.js
index 4eb3f6af..d872b0f3 100644
--- a/server/database/queries/provider.js
+++ b/server/database/queries/provider.js
@@ -17,7 +17,7 @@ export const fetchProvider = async (provider) => {
.where({ provider })
.first();
- return providerData;
+ return { ...providerData, data: JSON.parse(providerData?.data || '{}') };
};
export const fetchProviders = async () => {
diff --git a/server/middleware/auth/callback/custom.js b/server/middleware/auth/callback/custom.js
index 458fd872..48c485e7 100644
--- a/server/middleware/auth/callback/custom.js
+++ b/server/middleware/auth/callback/custom.js
@@ -2,20 +2,25 @@
import axios from 'axios';
// import local files
-import { getAuthCallbackUrl } from '../../../../shared/utils/authenication.js';
-import { fetchProvider } from '../../../database/queries/provider.js';
import config from '../../../utils/config.js';
+import { fetchProvider } from '../../../database/queries/provider.js';
+import { handleError } from '../../../utils/errors.js';
+import { getAuthCallbackUrl } from '../../../../shared/utils/authenication.js';
-const customCallback = async (request, response) => {
+const customCallback = async (request, response, next) => {
try {
const { code } = request.query;
- if (!code) return response.status(400).send('No code provided');
+ if (!code) {
+ return response.redirect('/error?code=missing_code&provider=custom');
+ }
const provider = await fetchProvider('custom');
if (!provider) {
- return response.redirect('/auth/error');
+ return response.redirect(
+ '/auth/error?code=provider_not_found&provider=custom'
+ );
}
const websiteUrl = config.get('websiteUrl');
@@ -28,17 +33,30 @@ const customCallback = async (request, response) => {
`${websiteUrl}/api/auth/callback/custom`
);
- const { data } = await axios.post(...params);
+ const { data } = await axios.post(provider.data.tokenUrl, ...params);
const { access_token } = data;
- const userInfo = await axios.get('https://custom-provider.com/api/user', {
+ const userInfoResponse = await axios.get(provider.data.userInfoUrl, {
headers: { Authorization: `Bearer ${access_token}` },
});
- return response.send(userInfo.data);
+ const user = userInfoResponse.data;
+ if (!user || !user.email) {
+ return response.redirect('/error?code=unverified_user&provider=custom');
+ }
+
+ response.locals.authUser = {
+ id: user.id || user.sub,
+ email: user.email,
+ avatar: user.avatar || user.picture,
+ username: user.username || user.name || 'unknown',
+ provider: 'custom',
+ };
+
+ return next();
} catch (error) {
- console.log(error);
+ handleError(error, response);
}
};
diff --git a/server/middleware/auth/platform.js b/server/middleware/auth/platform.js
index 56498a17..982732aa 100644
--- a/server/middleware/auth/platform.js
+++ b/server/middleware/auth/platform.js
@@ -19,7 +19,8 @@ const redirectUsingProviderMiddleware = async (request, response) => {
const redirectUrl = getAuthRedirectUrl(
provider.provider,
provider.clientId,
- `${websiteUrl}/api/auth/callback/${provider.provider}`
+ `${websiteUrl}/api/auth/callback/${provider.provider}`,
+ provider.data?.authUrl
);
return response.redirect(redirectUrl);
diff --git a/server/middleware/provider/getAll.js b/server/middleware/provider/getAll.js
index 5717b51c..2107eb00 100644
--- a/server/middleware/provider/getAll.js
+++ b/server/middleware/provider/getAll.js
@@ -4,9 +4,15 @@ import { fetchProviders } from '../../database/queries/provider.js';
const getAllProvidersMiddleware = async (request, response) => {
try {
const query = await fetchProviders();
- response.json(query);
+
+ const providers = query.map((provider) => ({
+ ...provider,
+ data: provider.data ? JSON.parse(provider.data) : {},
+ }));
+
+ return response.json(providers);
} catch (error) {
- handleError(error, response);
+ return handleError(error, response);
}
};
diff --git a/server/routes/auth.js b/server/routes/auth.js
index f544f2b6..a3cfbe66 100644
--- a/server/routes/auth.js
+++ b/server/routes/auth.js
@@ -24,7 +24,7 @@ router.post('/login', login);
router.get('/logout', logout);
router.get('/platform/:provider', redirectUsingProviderMiddleware);
-router.get('/callback/custom', customCallback);
+router.get('/callback/custom', customCallback, signInOrRegisterUsingAuth);
router.get('/callback/discord', discordCallback, signInOrRegisterUsingAuth);
router.get('/callback/github', githubCallback, signInOrRegisterUsingAuth);
router.get('/callback/google', googleCallback, signInOrRegisterUsingAuth);
diff --git a/server/routes/user.js b/server/routes/user.js
index a8788234..c0bcadf8 100644
--- a/server/routes/user.js
+++ b/server/routes/user.js
@@ -24,6 +24,8 @@ router.get('/', fetchUserMiddleware);
router.post('/exists', userExistsMiddleware);
+router.post('/delete/account', deleteAccountMiddleware);
+
router.get(
'/monitors',
hasRequiredPermission(PermissionsBits.VIEW_MONITORS),
@@ -58,6 +60,4 @@ router.post('/permission/update', permissionUpdateMiddleware);
router.post('/transfer/ownership', transferOwnershipMiddleware);
-router.post('/delete/account', deleteAccountMiddleware);
-
export default router;
diff --git a/shared/constants/provider.js b/shared/constants/provider.js
index 42ce7a0d..47479e6e 100644
--- a/shared/constants/provider.js
+++ b/shared/constants/provider.js
@@ -1,10 +1,10 @@
export const providers = [
- // {
- // id: 'custom',
- // name: 'Custom Provider',
- // description: 'Setup a custom provider like Authentik, Keycloak, etc.',
- // icon: '/logo.svg',
- // },
+ {
+ id: 'custom',
+ name: 'Custom Provider',
+ description: 'Setup a custom provider like Authentik, Keycloak, etc.',
+ icon: '/logo.svg',
+ },
{
id: 'discord',
name: 'Discord',
diff --git a/shared/utils/authenication.js b/shared/utils/authenication.js
index b790d34c..c6418d66 100644
--- a/shared/utils/authenication.js
+++ b/shared/utils/authenication.js
@@ -1,4 +1,9 @@
-export const getAuthRedirectUrl = (provider, clientId, redirectUri) => {
+export const getAuthRedirectUrl = (
+ provider,
+ clientId,
+ redirectUri,
+ authUrl
+) => {
const queryParams = {
client_id: clientId,
redirect_uri: redirectUri,
@@ -67,6 +72,10 @@ export const getAuthRedirectUrl = (provider, clientId, redirectUri) => {
}
if (provider === 'custom') {
+ queryParams.response_type = 'code';
+ queryParams.scope = 'openid profile email';
+
+ return authUrl + '?' + new URLSearchParams(queryParams).toString();
}
return null;
@@ -145,7 +154,13 @@ export const getAuthCallbackUrl = (
}
if (provider === 'custom') {
- return [];
+ return [
+ new URLSearchParams({
+ ...queryParams,
+ grant_type: 'authorization_code',
+ }).toString(),
+ { headers: { 'Content-Type': 'application/x-www-form-urlencoded' } },
+ ];
}
return null;
diff --git a/test/server/middleware/auth/callback/custom.test.js b/test/server/middleware/auth/callback/custom.test.js
index b1416404..554aee3e 100644
--- a/test/server/middleware/auth/callback/custom.test.js
+++ b/test/server/middleware/auth/callback/custom.test.js
@@ -10,51 +10,89 @@ vi.mock('../../../../../server/utils/config.js');
describe('customCallback', () => {
let fakeRequest, fakeResponse;
+ let next;
beforeEach(() => {
fakeRequest = createRequest();
fakeResponse = createResponse();
-
fakeRequest.query = { code: 'abc' };
fakeResponse.redirect = vi.fn();
- fakeResponse.status = vi.fn().mockReturnThis();
- fakeResponse.send = vi.fn();
fakeResponse.locals = {};
+ next = vi.fn();
});
afterEach(() => {
vi.clearAllMocks();
});
- it('should return 400 if no code provided', async () => {
+ it('should redirect if no code provided', async () => {
fakeRequest.query.code = undefined;
- await customCallback(fakeRequest, fakeResponse);
+ await customCallback(fakeRequest, fakeResponse, next);
- expect(fakeResponse.status).toHaveBeenCalledWith(400);
- expect(fakeResponse.send).toHaveBeenCalledWith('No code provided');
+ expect(fakeResponse.redirect).toHaveBeenCalledWith(
+ '/error?code=missing_code&provider=custom'
+ );
+ expect(next).not.toHaveBeenCalled();
});
it('should redirect if provider not found', async () => {
fetchProvider.mockResolvedValue(null);
- await customCallback(fakeRequest, fakeResponse);
+ await customCallback(fakeRequest, fakeResponse, next);
- expect(fakeResponse.redirect).toHaveBeenCalledWith('/auth/error');
+ expect(fakeResponse.redirect).toHaveBeenCalledWith(
+ '/auth/error?code=provider_not_found&provider=custom'
+ );
+ expect(next).not.toHaveBeenCalled();
});
- it('should send userInfo if provider and code are valid', async () => {
+ it('should set authUser and call next if provider and code are valid', async () => {
fetchProvider.mockResolvedValue({
provider: 'custom',
clientId: 'id',
clientSecret: 'secret',
+ data: {
+ tokenUrl: 'https://site.com/token',
+ userInfoUrl: 'https://site.com/userinfo',
+ },
});
config.get.mockReturnValue('https://site.com');
axios.post.mockResolvedValue({ data: { access_token: 'token' } });
- axios.get.mockResolvedValue({ data: { id: 'i', email: 'e' } });
+ axios.get.mockResolvedValue({
+ data: { id: 'i', email: 'e', avatar: 'a', username: 'u' },
+ });
+
+ await customCallback(fakeRequest, fakeResponse, next);
+
+ expect(fakeResponse.locals.authUser).toEqual({
+ id: 'i',
+ email: 'e',
+ avatar: 'a',
+ username: 'u',
+ provider: 'custom',
+ });
+ expect(next).toHaveBeenCalled();
+ });
+ it('should redirect if user info is missing or email is not present', async () => {
+ fetchProvider.mockResolvedValue({
+ provider: 'custom',
+ clientId: 'id',
+ clientSecret: 'secret',
+ data: {
+ tokenUrl: 'https://site.com/token',
+ userInfoUrl: 'https://site.com/userinfo',
+ },
+ });
+ config.get.mockReturnValue('https://site.com');
+ axios.post.mockResolvedValue({ data: { access_token: 'token' } });
+ axios.get.mockResolvedValue({ data: {} });
- await customCallback(fakeRequest, fakeResponse);
+ await customCallback(fakeRequest, fakeResponse, next);
- expect(fakeResponse.send).toHaveBeenCalledWith({ id: 'i', email: 'e' });
+ expect(fakeResponse.redirect).toHaveBeenCalledWith(
+ '/error?code=unverified_user&provider=custom'
+ );
+ expect(next).not.toHaveBeenCalled();
});
});
diff --git a/test/server/middleware/auth/platform.test.js b/test/server/middleware/auth/platform.test.js
index 6c960220..e6a76127 100644
--- a/test/server/middleware/auth/platform.test.js
+++ b/test/server/middleware/auth/platform.test.js
@@ -59,7 +59,8 @@ describe('redirectUsingProviderMiddleware', () => {
expect(getAuthRedirectUrl).toHaveBeenCalledWith(
'google',
'abc',
- 'https://site.com/api/auth/callback/google'
+ 'https://site.com/api/auth/callback/google',
+ undefined
);
expect(fakeResponse.redirect).toHaveBeenCalledWith('https://auth.url');
});
diff --git a/test/server/middleware/provider/getAll.test.js b/test/server/middleware/provider/getAll.test.js
index ba230337..9c026235 100644
--- a/test/server/middleware/provider/getAll.test.js
+++ b/test/server/middleware/provider/getAll.test.js
@@ -25,7 +25,9 @@ describe('getAllProvidersMiddleware', () => {
await getAllProvidersMiddleware(fakeRequest, fakeResponse);
expect(fetchProviders).toHaveBeenCalled();
- expect(fakeResponse._getJSONData()).toEqual([{ provider: 'github' }]);
+ expect(fakeResponse._getJSONData()).toEqual([
+ { provider: 'github', data: {} },
+ ]);
expect(handleError).not.toHaveBeenCalled();
});