mirror of
https://github.com/lowdefy/lowdefy.git
synced 2025-04-12 15:40:30 +08:00
Merge pull request #498 from lowdefy/fix-netlify-openid
fix(server-netlify): Fix auth token cookie path.
This commit is contained in:
commit
ec980dfaa7
@ -22,11 +22,12 @@ import createGetLoader from './getLoader';
|
||||
import verifyAccessToken from './verifyAccessToken';
|
||||
|
||||
function createContext(config) {
|
||||
const { CONFIGURATION_BASE_PATH, development, getSecrets, logger } = config;
|
||||
const { CONFIGURATION_BASE_PATH, development, getSecrets, logger, gqlUri } = config;
|
||||
const bootstrapContext = {
|
||||
CONFIGURATION_BASE_PATH,
|
||||
development,
|
||||
getSecrets,
|
||||
gqlUri,
|
||||
logger,
|
||||
};
|
||||
|
||||
|
@ -19,7 +19,7 @@
|
||||
import { get } from '@lowdefy/helpers';
|
||||
import cookie from 'cookie';
|
||||
|
||||
async function verifyAccessToken({ development, headers, getController, setHeader }) {
|
||||
async function verifyAccessToken({ development, headers, getController, gqlUri, setHeader }) {
|
||||
const cookieHeader = get(headers, 'Cookie') || get(headers, 'cookie') || '';
|
||||
const { authorization } = cookie.parse(cookieHeader);
|
||||
if (!authorization) return {};
|
||||
@ -37,7 +37,7 @@ async function verifyAccessToken({ development, headers, getController, setHeade
|
||||
} catch (error) {
|
||||
const setCookieHeader = cookie.serialize('authorization', '', {
|
||||
httpOnly: true,
|
||||
path: '/api/graphql',
|
||||
path: gqlUri || '/api/graphql',
|
||||
sameSite: 'lax',
|
||||
secure: !development,
|
||||
maxAge: 0,
|
||||
|
@ -122,3 +122,22 @@ test('development header', async () => {
|
||||
['Set-Cookie', 'authorization=; Max-Age=0; Path=/api/graphql; HttpOnly; SameSite=Lax'],
|
||||
]);
|
||||
});
|
||||
|
||||
test('configure gqlUri', async () => {
|
||||
const cookie = await createCookieHeader({ expired: true });
|
||||
|
||||
let bootstrapContext = testBootstrapContext({
|
||||
headers: { cookie },
|
||||
getSecrets,
|
||||
gqlUri: '/custom/graphql',
|
||||
setHeader,
|
||||
});
|
||||
await expect(verifyAccessToken(bootstrapContext)).rejects.toThrow(TokenExpiredError);
|
||||
expect(setHeader.mock.calls).toEqual([
|
||||
[
|
||||
'Set-Cookie',
|
||||
'authorization=; Max-Age=0; Path=/custom/graphql; HttpOnly; Secure; SameSite=Lax',
|
||||
],
|
||||
]);
|
||||
await expect(verifyAccessToken(bootstrapContext)).rejects.toThrow('Token expired.');
|
||||
});
|
||||
|
@ -21,7 +21,7 @@ import cookie from 'cookie';
|
||||
import { AuthenticationError, ConfigurationError } from '../context/errors';
|
||||
|
||||
class OpenIdController {
|
||||
constructor({ development, getController, getLoader, getSecrets, host, setHeader }) {
|
||||
constructor({ development, getController, getLoader, getSecrets, gqlUri, host, setHeader }) {
|
||||
const httpPrefix = development ? 'http' : 'https';
|
||||
|
||||
this.development = development;
|
||||
@ -29,6 +29,7 @@ class OpenIdController {
|
||||
this.getSecrets = getSecrets;
|
||||
this.host = host;
|
||||
this.redirectUri = `${httpPrefix}://${host}/auth/openid-callback`;
|
||||
this.gqlUri = gqlUri || '/api/graphql';
|
||||
this.setHeader = setHeader;
|
||||
this.tokenController = getController('token');
|
||||
}
|
||||
@ -102,7 +103,7 @@ class OpenIdController {
|
||||
const accessToken = await this.tokenController.issueAccessToken(claims);
|
||||
const setCookieHeader = cookie.serialize('authorization', accessToken, {
|
||||
httpOnly: true,
|
||||
path: '/api/graphql',
|
||||
path: this.gqlUri,
|
||||
sameSite: 'lax',
|
||||
secure: !this.development,
|
||||
});
|
||||
@ -140,7 +141,7 @@ class OpenIdController {
|
||||
try {
|
||||
const setCookieHeader = cookie.serialize('authorization', '', {
|
||||
httpOnly: true,
|
||||
path: '/api/graphql',
|
||||
path: this.gqlUri,
|
||||
sameSite: 'lax',
|
||||
secure: !this.development,
|
||||
maxAge: 0,
|
||||
|
@ -320,6 +320,27 @@ describe('callback', () => {
|
||||
);
|
||||
expect(setHeader.mock.calls).toEqual([]);
|
||||
});
|
||||
|
||||
test('configure gqlUri', async () => {
|
||||
getSecrets.mockImplementation(() => secrets);
|
||||
const testContext = testBootstrapContext({
|
||||
getSecrets,
|
||||
gqlUri: '/custom/graphql',
|
||||
host: 'host',
|
||||
loaders,
|
||||
setHeader,
|
||||
});
|
||||
const openIdController = createOpenIdController(testContext);
|
||||
const tokenController = createTokenController(testContext);
|
||||
const state = await tokenController.issueOpenIdStateToken(authorizationUrlInput);
|
||||
await openIdController.callback({ code: 'code', state });
|
||||
expect(setHeader.mock.calls).toEqual([
|
||||
[
|
||||
'Set-Cookie',
|
||||
'authorization=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiJzdWIiLCJsb3dkZWZ5X2FjY2Vzc190b2tlbiI6dHJ1ZSwiaWF0IjoxLCJleHAiOjE0NDAxLCJhdWQiOiJob3N0IiwiaXNzIjoiaG9zdCJ9.oADZ37ERfvONPBGiFsStQUOEHO6BaX_zkGXCHY8PbRA; Path=/custom/graphql; HttpOnly; Secure; SameSite=Lax',
|
||||
],
|
||||
]);
|
||||
});
|
||||
});
|
||||
|
||||
describe('logout', () => {
|
||||
@ -476,4 +497,23 @@ describe('logout', () => {
|
||||
],
|
||||
]);
|
||||
});
|
||||
|
||||
test('configure gqlUri', async () => {
|
||||
const testContext = testBootstrapContext({
|
||||
getSecrets,
|
||||
gqlUri: '/custom/graphql',
|
||||
host: 'host',
|
||||
loaders,
|
||||
setHeader,
|
||||
});
|
||||
getSecrets.mockImplementation(() => secrets);
|
||||
const openIdController = createOpenIdController(testContext);
|
||||
await openIdController.logoutUrl(logoutUrlInput);
|
||||
expect(setHeader.mock.calls).toEqual([
|
||||
[
|
||||
'Set-Cookie',
|
||||
'authorization=; Max-Age=0; Path=/custom/graphql; HttpOnly; Secure; SameSite=Lax',
|
||||
],
|
||||
]);
|
||||
});
|
||||
});
|
||||
|
@ -19,6 +19,7 @@ import createGetController from '../controllers/getController';
|
||||
function testBootstrapContext({
|
||||
development,
|
||||
getSecrets,
|
||||
gqlUri,
|
||||
headers,
|
||||
host,
|
||||
loaders,
|
||||
@ -31,6 +32,7 @@ function testBootstrapContext({
|
||||
getController: () => {},
|
||||
getLoader: loaders ? (name) => loaders[name] : () => {},
|
||||
getSecrets: getSecrets || (() => {}),
|
||||
gqlUri,
|
||||
headers: headers || {},
|
||||
host: host || 'host',
|
||||
logger: { log: () => {} },
|
||||
@ -41,11 +43,21 @@ function testBootstrapContext({
|
||||
return bootstrapContext;
|
||||
}
|
||||
|
||||
function testContext({ development, getSecrets, host, loaders, setHeader, user, headers } = {}) {
|
||||
function testContext({
|
||||
development,
|
||||
getSecrets,
|
||||
gqlUri,
|
||||
host,
|
||||
loaders,
|
||||
setHeader,
|
||||
user,
|
||||
headers,
|
||||
} = {}) {
|
||||
const bootstrapContext = {
|
||||
development,
|
||||
getLoader: (name) => loaders[name],
|
||||
getSecrets: getSecrets || (() => {}),
|
||||
gqlUri,
|
||||
host: host || 'host',
|
||||
headers: headers || {},
|
||||
logger: { log: () => {} },
|
||||
|
@ -24,6 +24,7 @@ import { createGetSecretsFromEnv } from '@lowdefy/node-utils';
|
||||
const config = {
|
||||
CONFIGURATION_BASE_PATH: path.resolve(__dirname, './build'),
|
||||
getSecrets: createGetSecretsFromEnv(),
|
||||
gqlUri: '/.netlify/functions/graphql',
|
||||
logger: console,
|
||||
};
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user