fix(core): Some more browser-id related fixes (no-changelog) (#9102)

This commit is contained in:
कारतोफ्फेलस्क्रिप्ट™ 2024-04-10 10:37:23 +02:00 committed by GitHub
parent 3e231dbfe6
commit a7108d14f9
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
3 changed files with 21 additions and 7 deletions

View file

@ -41,7 +41,7 @@ export function createPage({
? loadPreviousSession ? loadPreviousSession
: 'notSupported'; : 'notSupported';
return `<doctype html> return `<!doctype html>
<html lang="en"> <html lang="en">
<head> <head>
<meta charset="utf-8"> <meta charset="utf-8">
@ -60,7 +60,8 @@ export function createPage({
if (authentication === 'n8nUserAuth') { if (authentication === 'n8nUserAuth') {
try { try {
const response = await fetch('/rest/login', { const response = await fetch('/rest/login', {
method: 'GET' method: 'GET',
headers: { 'browser-id': localStorage.getItem('n8n-browserId') }
}); });
if (response.status !== 200) { if (response.status !== 200) {

View file

@ -33,7 +33,16 @@ interface PasswordResetToken {
hash: string; hash: string;
} }
const pushEndpoint = `/${config.get('endpoints.rest')}/push`; const restEndpoint = config.get('endpoints.rest');
// The browser-id check needs to be skipped on these endpoints
const skipBrowserIdCheckEndpoints = [
// we need to exclude push endpoint because we can't send custom header on websocket requests
// TODO: Implement a custom handshake for push, to avoid having to send any data on querystring or headers
`/${restEndpoint}/push`,
// We need to exclude binary-data downloading endpoint because we can't send custom headers on `<embed>` tags
`/${restEndpoint}/binary-data`,
];
@Service() @Service()
export class AuthService { export class AuthService {
@ -120,9 +129,7 @@ export class AuthService {
// or, If the email or password has been updated // or, If the email or password has been updated
jwtPayload.hash !== this.createJWTHash(user) || jwtPayload.hash !== this.createJWTHash(user) ||
// If the token was issued for another browser session // If the token was issued for another browser session
// NOTE: we need to exclude push endpoint from this check because we can't send custom header on websocket requests (!skipBrowserIdCheckEndpoints.includes(req.baseUrl) &&
// TODO: Implement a custom handshake for push, to avoid having to send any data on querystring or headers
(req.baseUrl !== pushEndpoint &&
jwtPayload.browserId && jwtPayload.browserId &&
(!req.browserId || jwtPayload.browserId !== this.hash(req.browserId))) (!req.browserId || jwtPayload.browserId !== this.hash(req.browserId)))
) { ) {

View file

@ -22,6 +22,7 @@ import { PUBLIC_API_REST_PATH_SEGMENT, REST_PATH_SEGMENT } from '../constants';
import type { SetupProps, TestServer } from '../types'; import type { SetupProps, TestServer } from '../types';
import { LicenseMocker } from '../license'; import { LicenseMocker } from '../license';
import { AuthService } from '@/auth/auth.service'; import { AuthService } from '@/auth/auth.service';
import type { APIRequest } from '@/requests';
/** /**
* Plugin to prefix a path segment into a request URL pathname. * Plugin to prefix a path segment into a request URL pathname.
@ -43,11 +44,12 @@ function prefix(pathSegment: string) {
}; };
} }
const browserId = 'test-browser-id';
function createAgent(app: express.Application, options?: { auth: boolean; user: User }) { function createAgent(app: express.Application, options?: { auth: boolean; user: User }) {
const agent = request.agent(app); const agent = request.agent(app);
void agent.use(prefix(REST_PATH_SEGMENT)); void agent.use(prefix(REST_PATH_SEGMENT));
if (options?.auth && options?.user) { if (options?.auth && options?.user) {
const token = Container.get(AuthService).issueJWT(options.user); const token = Container.get(AuthService).issueJWT(options.user, browserId);
agent.jar.setCookie(`${AUTH_COOKIE_NAME}=${token}`); agent.jar.setCookie(`${AUTH_COOKIE_NAME}=${token}`);
} }
return agent; return agent;
@ -73,6 +75,10 @@ export const setupTestServer = ({
const app = express(); const app = express();
app.use(rawBodyReader); app.use(rawBodyReader);
app.use(cookieParser()); app.use(cookieParser());
app.use((req: APIRequest, _, next) => {
req.browserId = browserId;
next();
});
// Mock all telemetry and logging // Mock all telemetry and logging
mockInstance(Logger); mockInstance(Logger);