mirror of
https://github.com/documenso/documenso.git
synced 2025-11-20 03:32:14 +10:00
fix: wip
This commit is contained in:
@ -5,8 +5,9 @@ import { formatDocumentsPath } from '@documenso/lib/utils/teams';
|
|||||||
|
|
||||||
export function loader() {
|
export function loader() {
|
||||||
const { currentTeam } = getLoaderSession();
|
const { currentTeam } = getLoaderSession();
|
||||||
|
|
||||||
if (!currentTeam) {
|
if (!currentTeam) {
|
||||||
throw redirect('/documents');
|
throw redirect('/settings/teams');
|
||||||
}
|
}
|
||||||
|
|
||||||
throw redirect(formatDocumentsPath(currentTeam.url));
|
throw redirect(formatDocumentsPath(currentTeam.url));
|
||||||
|
|||||||
@ -19,7 +19,7 @@ export const loader = () => {
|
|||||||
const { currentTeam } = getLoaderSession();
|
const { currentTeam } = getLoaderSession();
|
||||||
|
|
||||||
if (!currentTeam) {
|
if (!currentTeam) {
|
||||||
throw redirect('/documents');
|
throw redirect('/settings/teams');
|
||||||
}
|
}
|
||||||
|
|
||||||
const trpcHeaders = {
|
const trpcHeaders = {
|
||||||
|
|||||||
@ -97,7 +97,6 @@
|
|||||||
"typescript": "5.6.2",
|
"typescript": "5.6.2",
|
||||||
"vite": "^6.1.0",
|
"vite": "^6.1.0",
|
||||||
"vite-plugin-babel-macros": "^1.0.6",
|
"vite-plugin-babel-macros": "^1.0.6",
|
||||||
"vite-plugin-checker": "^0.8.0",
|
|
||||||
"vite-tsconfig-paths": "^5.1.4"
|
"vite-tsconfig-paths": "^5.1.4"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1,7 +1,6 @@
|
|||||||
import type { Context, Next } from 'hono';
|
import type { Context, Next } from 'hono';
|
||||||
import { getCookie } from 'hono/cookie';
|
import { getCookie } from 'hono/cookie';
|
||||||
|
|
||||||
import { setCsrfCookie } from '@documenso/auth/server/lib/session/session-cookies';
|
|
||||||
import { AppLogger } from '@documenso/lib/utils/debugger';
|
import { AppLogger } from '@documenso/lib/utils/debugger';
|
||||||
|
|
||||||
const logger = new AppLogger('Middleware');
|
const logger = new AppLogger('Middleware');
|
||||||
@ -32,14 +31,6 @@ export const appMiddleware = async (c: Context, next: Next) => {
|
|||||||
const referrerUrl = referrer ? new URL(referrer) : null;
|
const referrerUrl = referrer ? new URL(referrer) : null;
|
||||||
const referrerPathname = referrerUrl ? referrerUrl.pathname : null;
|
const referrerPathname = referrerUrl ? referrerUrl.pathname : null;
|
||||||
|
|
||||||
// Set csrf token if not set.
|
|
||||||
const csrfToken = getCookie(c, 'csrfToken');
|
|
||||||
|
|
||||||
// Todo: Currently not working.
|
|
||||||
if (!csrfToken) {
|
|
||||||
await setCsrfCookie(c);
|
|
||||||
}
|
|
||||||
|
|
||||||
// // Whether to reset the preferred team url cookie if the user accesses a non team page from a team page.
|
// // Whether to reset the preferred team url cookie if the user accesses a non team page from a team page.
|
||||||
// const resetPreferredTeamUrl =
|
// const resetPreferredTeamUrl =
|
||||||
// referrerPathname &&
|
// referrerPathname &&
|
||||||
@ -59,24 +50,6 @@ export const appMiddleware = async (c: Context, next: Next) => {
|
|||||||
// return c.redirect(redirectUrl);
|
// return c.redirect(redirectUrl);
|
||||||
// }
|
// }
|
||||||
|
|
||||||
// // Redirect `/t` to `/settings/teams`.
|
|
||||||
// if (path === '/t' || path === '/t/') {
|
|
||||||
// logger.log('Redirecting to /settings/teams');
|
|
||||||
|
|
||||||
// const redirectUrl = new URL('/settings/teams', req.url);
|
|
||||||
// return c.redirect(redirectUrl);
|
|
||||||
// }
|
|
||||||
|
|
||||||
// // Redirect `/t/<team_url>` to `/t/<team_url>/documents`.
|
|
||||||
// if (TEAM_URL_ROOT_REGEX.test(path)) {
|
|
||||||
// logger.log('Redirecting team documents');
|
|
||||||
|
|
||||||
// const redirectUrl = new URL(`${path}/documents`, req.url);
|
|
||||||
// setCookie(c, 'preferred-team-url', path.replace('/t/', ''));
|
|
||||||
|
|
||||||
// return c.redirect(redirectUrl);
|
|
||||||
// }
|
|
||||||
|
|
||||||
// // Set the preferred team url cookie if user accesses a team page.
|
// // Set the preferred team url cookie if user accesses a team page.
|
||||||
// if (path.startsWith('/t/')) {
|
// if (path.startsWith('/t/')) {
|
||||||
// setCookie(c, 'preferred-team-url', path.split('/')[2]);
|
// setCookie(c, 'preferred-team-url', path.split('/')[2]);
|
||||||
@ -90,6 +63,4 @@ export const appMiddleware = async (c: Context, next: Next) => {
|
|||||||
// deleteCookie(c, 'preferred-team-url');
|
// deleteCookie(c, 'preferred-team-url');
|
||||||
// return next();
|
// return next();
|
||||||
// }
|
// }
|
||||||
|
|
||||||
return next();
|
|
||||||
};
|
};
|
||||||
|
|||||||
@ -9,7 +9,6 @@ import { openApiDocument } from '@documenso/trpc/server/open-api';
|
|||||||
|
|
||||||
import { filesRoute } from './api/files';
|
import { filesRoute } from './api/files';
|
||||||
import { type AppContext, appContext } from './context';
|
import { type AppContext, appContext } from './context';
|
||||||
import { appMiddleware } from './middleware';
|
|
||||||
import { openApiTrpcServerHandler } from './trpc/hono-trpc-open-api';
|
import { openApiTrpcServerHandler } from './trpc/hono-trpc-open-api';
|
||||||
import { reactRouterTrpcServer } from './trpc/hono-trpc-remix';
|
import { reactRouterTrpcServer } from './trpc/hono-trpc-remix';
|
||||||
|
|
||||||
@ -30,7 +29,7 @@ app.use(appContext);
|
|||||||
/**
|
/**
|
||||||
* Middleware for initial page loads.
|
* Middleware for initial page loads.
|
||||||
*/
|
*/
|
||||||
app.use('*', appMiddleware);
|
// app.use('*', appMiddleware);
|
||||||
|
|
||||||
// Auth server.
|
// Auth server.
|
||||||
app.route('/api/auth', auth);
|
app.route('/api/auth', auth);
|
||||||
|
|||||||
192
package-lock.json
generated
192
package-lock.json
generated
@ -179,7 +179,6 @@
|
|||||||
"typescript": "5.6.2",
|
"typescript": "5.6.2",
|
||||||
"vite": "^6.1.0",
|
"vite": "^6.1.0",
|
||||||
"vite-plugin-babel-macros": "^1.0.6",
|
"vite-plugin-babel-macros": "^1.0.6",
|
||||||
"vite-plugin-checker": "^0.8.0",
|
|
||||||
"vite-tsconfig-paths": "^5.1.4"
|
"vite-tsconfig-paths": "^5.1.4"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@ -849,16 +848,6 @@
|
|||||||
"win32"
|
"win32"
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
"apps/remix/node_modules/commander": {
|
|
||||||
"version": "8.3.0",
|
|
||||||
"resolved": "https://registry.npmjs.org/commander/-/commander-8.3.0.tgz",
|
|
||||||
"integrity": "sha512-OkTL9umf+He2DZkUq8f8J9of7yL6RJKI24dVITBmNfZBmri9zYZQrKkuXiKhyfPSu8tUhnVBB1iKXevvnlR4Ww==",
|
|
||||||
"dev": true,
|
|
||||||
"license": "MIT",
|
|
||||||
"engines": {
|
|
||||||
"node": ">= 12"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"apps/remix/node_modules/esbuild": {
|
"apps/remix/node_modules/esbuild": {
|
||||||
"version": "0.24.2",
|
"version": "0.24.2",
|
||||||
"resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.24.2.tgz",
|
"resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.24.2.tgz",
|
||||||
@ -900,35 +889,6 @@
|
|||||||
"@esbuild/win32-x64": "0.24.2"
|
"@esbuild/win32-x64": "0.24.2"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"apps/remix/node_modules/meow": {
|
|
||||||
"version": "9.0.0",
|
|
||||||
"resolved": "https://registry.npmjs.org/meow/-/meow-9.0.0.tgz",
|
|
||||||
"integrity": "sha512-+obSblOQmRhcyBt62furQqRAQpNyWXo8BuQ5bN7dG8wmwQ+vwHKp/rCFD4CrTP8CsDQD1sjoZ94K417XEUk8IQ==",
|
|
||||||
"dev": true,
|
|
||||||
"license": "MIT",
|
|
||||||
"optional": true,
|
|
||||||
"peer": true,
|
|
||||||
"dependencies": {
|
|
||||||
"@types/minimist": "^1.2.0",
|
|
||||||
"camelcase-keys": "^6.2.2",
|
|
||||||
"decamelize": "^1.2.0",
|
|
||||||
"decamelize-keys": "^1.1.0",
|
|
||||||
"hard-rejection": "^2.1.0",
|
|
||||||
"minimist-options": "4.1.0",
|
|
||||||
"normalize-package-data": "^3.0.0",
|
|
||||||
"read-pkg-up": "^7.0.1",
|
|
||||||
"redent": "^3.0.0",
|
|
||||||
"trim-newlines": "^3.0.0",
|
|
||||||
"type-fest": "^0.18.0",
|
|
||||||
"yargs-parser": "^20.2.3"
|
|
||||||
},
|
|
||||||
"engines": {
|
|
||||||
"node": ">=10"
|
|
||||||
},
|
|
||||||
"funding": {
|
|
||||||
"url": "https://github.com/sponsors/sindresorhus"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"apps/remix/node_modules/rollup": {
|
"apps/remix/node_modules/rollup": {
|
||||||
"version": "4.34.5",
|
"version": "4.34.5",
|
||||||
"resolved": "https://registry.npmjs.org/rollup/-/rollup-4.34.5.tgz",
|
"resolved": "https://registry.npmjs.org/rollup/-/rollup-4.34.5.tgz",
|
||||||
@ -968,88 +928,6 @@
|
|||||||
"fsevents": "~2.3.2"
|
"fsevents": "~2.3.2"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"apps/remix/node_modules/type-fest": {
|
|
||||||
"version": "0.18.1",
|
|
||||||
"resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.18.1.tgz",
|
|
||||||
"integrity": "sha512-OIAYXk8+ISY+qTOwkHtKqzAuxchoMiD9Udx+FSGQDuiRR+PJKJHc2NJAXlbhkGwTt/4/nKZxELY1w3ReWOL8mw==",
|
|
||||||
"dev": true,
|
|
||||||
"license": "(MIT OR CC0-1.0)",
|
|
||||||
"optional": true,
|
|
||||||
"peer": true,
|
|
||||||
"engines": {
|
|
||||||
"node": ">=10"
|
|
||||||
},
|
|
||||||
"funding": {
|
|
||||||
"url": "https://github.com/sponsors/sindresorhus"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"apps/remix/node_modules/vite-plugin-checker": {
|
|
||||||
"version": "0.8.0",
|
|
||||||
"resolved": "https://registry.npmjs.org/vite-plugin-checker/-/vite-plugin-checker-0.8.0.tgz",
|
|
||||||
"integrity": "sha512-UA5uzOGm97UvZRTdZHiQVYFnd86AVn8EVaD4L3PoVzxH+IZSfaAw14WGFwX9QS23UW3lV/5bVKZn6l0w+q9P0g==",
|
|
||||||
"dev": true,
|
|
||||||
"license": "MIT",
|
|
||||||
"dependencies": {
|
|
||||||
"@babel/code-frame": "^7.12.13",
|
|
||||||
"ansi-escapes": "^4.3.0",
|
|
||||||
"chalk": "^4.1.1",
|
|
||||||
"chokidar": "^3.5.1",
|
|
||||||
"commander": "^8.0.0",
|
|
||||||
"fast-glob": "^3.2.7",
|
|
||||||
"fs-extra": "^11.1.0",
|
|
||||||
"npm-run-path": "^4.0.1",
|
|
||||||
"strip-ansi": "^6.0.0",
|
|
||||||
"tiny-invariant": "^1.1.0",
|
|
||||||
"vscode-languageclient": "^7.0.0",
|
|
||||||
"vscode-languageserver": "^7.0.0",
|
|
||||||
"vscode-languageserver-textdocument": "^1.0.1",
|
|
||||||
"vscode-uri": "^3.0.2"
|
|
||||||
},
|
|
||||||
"engines": {
|
|
||||||
"node": ">=14.16"
|
|
||||||
},
|
|
||||||
"peerDependencies": {
|
|
||||||
"@biomejs/biome": ">=1.7",
|
|
||||||
"eslint": ">=7",
|
|
||||||
"meow": "^9.0.0",
|
|
||||||
"optionator": "^0.9.1",
|
|
||||||
"stylelint": ">=13",
|
|
||||||
"typescript": "*",
|
|
||||||
"vite": ">=2.0.0",
|
|
||||||
"vls": "*",
|
|
||||||
"vti": "*",
|
|
||||||
"vue-tsc": "~2.1.6"
|
|
||||||
},
|
|
||||||
"peerDependenciesMeta": {
|
|
||||||
"@biomejs/biome": {
|
|
||||||
"optional": true
|
|
||||||
},
|
|
||||||
"eslint": {
|
|
||||||
"optional": true
|
|
||||||
},
|
|
||||||
"meow": {
|
|
||||||
"optional": true
|
|
||||||
},
|
|
||||||
"optionator": {
|
|
||||||
"optional": true
|
|
||||||
},
|
|
||||||
"stylelint": {
|
|
||||||
"optional": true
|
|
||||||
},
|
|
||||||
"typescript": {
|
|
||||||
"optional": true
|
|
||||||
},
|
|
||||||
"vls": {
|
|
||||||
"optional": true
|
|
||||||
},
|
|
||||||
"vti": {
|
|
||||||
"optional": true
|
|
||||||
},
|
|
||||||
"vue-tsc": {
|
|
||||||
"optional": true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"node_modules/@alloc/quick-lru": {
|
"node_modules/@alloc/quick-lru": {
|
||||||
"version": "5.2.0",
|
"version": "5.2.0",
|
||||||
"resolved": "https://registry.npmjs.org/@alloc/quick-lru/-/quick-lru-5.2.0.tgz",
|
"resolved": "https://registry.npmjs.org/@alloc/quick-lru/-/quick-lru-5.2.0.tgz",
|
||||||
@ -40093,69 +39971,6 @@
|
|||||||
"@esbuild/win32-x64": "0.24.2"
|
"@esbuild/win32-x64": "0.24.2"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/vscode-jsonrpc": {
|
|
||||||
"version": "6.0.0",
|
|
||||||
"resolved": "https://registry.npmjs.org/vscode-jsonrpc/-/vscode-jsonrpc-6.0.0.tgz",
|
|
||||||
"integrity": "sha512-wnJA4BnEjOSyFMvjZdpiOwhSq9uDoK8e/kpRJDTaMYzwlkrhG1fwDIZI94CLsLzlCK5cIbMMtFlJlfR57Lavmg==",
|
|
||||||
"dev": true,
|
|
||||||
"license": "MIT",
|
|
||||||
"engines": {
|
|
||||||
"node": ">=8.0.0 || >=10.0.0"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"node_modules/vscode-languageclient": {
|
|
||||||
"version": "7.0.0",
|
|
||||||
"resolved": "https://registry.npmjs.org/vscode-languageclient/-/vscode-languageclient-7.0.0.tgz",
|
|
||||||
"integrity": "sha512-P9AXdAPlsCgslpP9pRxYPqkNYV7Xq8300/aZDpO35j1fJm/ncize8iGswzYlcvFw5DQUx4eVk+KvfXdL0rehNg==",
|
|
||||||
"dev": true,
|
|
||||||
"license": "MIT",
|
|
||||||
"dependencies": {
|
|
||||||
"minimatch": "^3.0.4",
|
|
||||||
"semver": "^7.3.4",
|
|
||||||
"vscode-languageserver-protocol": "3.16.0"
|
|
||||||
},
|
|
||||||
"engines": {
|
|
||||||
"vscode": "^1.52.0"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"node_modules/vscode-languageserver": {
|
|
||||||
"version": "7.0.0",
|
|
||||||
"resolved": "https://registry.npmjs.org/vscode-languageserver/-/vscode-languageserver-7.0.0.tgz",
|
|
||||||
"integrity": "sha512-60HTx5ID+fLRcgdHfmz0LDZAXYEV68fzwG0JWwEPBode9NuMYTIxuYXPg4ngO8i8+Ou0lM7y6GzaYWbiDL0drw==",
|
|
||||||
"dev": true,
|
|
||||||
"license": "MIT",
|
|
||||||
"dependencies": {
|
|
||||||
"vscode-languageserver-protocol": "3.16.0"
|
|
||||||
},
|
|
||||||
"bin": {
|
|
||||||
"installServerIntoExtension": "bin/installServerIntoExtension"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"node_modules/vscode-languageserver-protocol": {
|
|
||||||
"version": "3.16.0",
|
|
||||||
"resolved": "https://registry.npmjs.org/vscode-languageserver-protocol/-/vscode-languageserver-protocol-3.16.0.tgz",
|
|
||||||
"integrity": "sha512-sdeUoAawceQdgIfTI+sdcwkiK2KU+2cbEYA0agzM2uqaUy2UpnnGHtWTHVEtS0ES4zHU0eMFRGN+oQgDxlD66A==",
|
|
||||||
"dev": true,
|
|
||||||
"license": "MIT",
|
|
||||||
"dependencies": {
|
|
||||||
"vscode-jsonrpc": "6.0.0",
|
|
||||||
"vscode-languageserver-types": "3.16.0"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"node_modules/vscode-languageserver-textdocument": {
|
|
||||||
"version": "1.0.12",
|
|
||||||
"resolved": "https://registry.npmjs.org/vscode-languageserver-textdocument/-/vscode-languageserver-textdocument-1.0.12.tgz",
|
|
||||||
"integrity": "sha512-cxWNPesCnQCcMPeenjKKsOCKQZ/L6Tv19DTRIGuLWe32lyzWhihGVJ/rcckZXJxfdKCFvRLS3fpBIsV/ZGX4zA==",
|
|
||||||
"dev": true,
|
|
||||||
"license": "MIT"
|
|
||||||
},
|
|
||||||
"node_modules/vscode-languageserver-types": {
|
|
||||||
"version": "3.16.0",
|
|
||||||
"resolved": "https://registry.npmjs.org/vscode-languageserver-types/-/vscode-languageserver-types-3.16.0.tgz",
|
|
||||||
"integrity": "sha512-k8luDIWJWyenLc5ToFQQMaSrqCHiLwyKPHKPQZ5zz21vM+vIVUSvsRpcbiECH4WR88K2XZqc4ScRcZ7nk/jbeA==",
|
|
||||||
"dev": true,
|
|
||||||
"license": "MIT"
|
|
||||||
},
|
|
||||||
"node_modules/vscode-oniguruma": {
|
"node_modules/vscode-oniguruma": {
|
||||||
"version": "1.7.0",
|
"version": "1.7.0",
|
||||||
"resolved": "https://registry.npmjs.org/vscode-oniguruma/-/vscode-oniguruma-1.7.0.tgz",
|
"resolved": "https://registry.npmjs.org/vscode-oniguruma/-/vscode-oniguruma-1.7.0.tgz",
|
||||||
@ -40168,13 +39983,6 @@
|
|||||||
"integrity": "sha512-AFbieoL7a5LMqcnOF04ji+rpXadgOXnZsxQr//r83kLPr7biP7am3g9zbaZIaBGwBRWeSvoMD4mgPdX3e4NWBg==",
|
"integrity": "sha512-AFbieoL7a5LMqcnOF04ji+rpXadgOXnZsxQr//r83kLPr7biP7am3g9zbaZIaBGwBRWeSvoMD4mgPdX3e4NWBg==",
|
||||||
"license": "MIT"
|
"license": "MIT"
|
||||||
},
|
},
|
||||||
"node_modules/vscode-uri": {
|
|
||||||
"version": "3.1.0",
|
|
||||||
"resolved": "https://registry.npmjs.org/vscode-uri/-/vscode-uri-3.1.0.tgz",
|
|
||||||
"integrity": "sha512-/BpdSx+yCQGnCvecbyXdxHDkuk55/G3xwnC0GqY4gmQ3j+A+g8kzzgB4Nk/SINjqn6+waqw3EgbVF2QKExkRxQ==",
|
|
||||||
"dev": true,
|
|
||||||
"license": "MIT"
|
|
||||||
},
|
|
||||||
"node_modules/wait-on": {
|
"node_modules/wait-on": {
|
||||||
"version": "8.0.2",
|
"version": "8.0.2",
|
||||||
"resolved": "https://registry.npmjs.org/wait-on/-/wait-on-8.0.2.tgz",
|
"resolved": "https://registry.npmjs.org/wait-on/-/wait-on-8.0.2.tgz",
|
||||||
|
|||||||
@ -53,8 +53,16 @@ export class AuthClient {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public emailPassword = {
|
public emailPassword = {
|
||||||
signIn: async (data: TEmailPasswordSignin) => {
|
signIn: async (data: Omit<TEmailPasswordSignin, 'csrfToken'>) => {
|
||||||
const response = await this.client['email-password'].authorize.$post({ json: data });
|
const { csrfToken } = await this.client.csrf.$get().then(async (res) => res.json());
|
||||||
|
|
||||||
|
const response = await this.client['email-password'].authorize.$post({
|
||||||
|
json: {
|
||||||
|
...data,
|
||||||
|
csrfToken,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
await this.handleError(response);
|
await this.handleError(response);
|
||||||
|
|
||||||
handleSignInRedirect(data.redirectPath);
|
handleSignInRedirect(data.redirectPath);
|
||||||
|
|||||||
@ -2,9 +2,11 @@ import { Hono } from 'hono';
|
|||||||
import { HTTPException } from 'hono/http-exception';
|
import { HTTPException } from 'hono/http-exception';
|
||||||
import type { ContentfulStatusCode } from 'hono/utils/http-status';
|
import type { ContentfulStatusCode } from 'hono/utils/http-status';
|
||||||
|
|
||||||
|
import { NEXT_PUBLIC_WEBAPP_URL } from '@documenso/lib/constants/app';
|
||||||
import { AppError, AppErrorCode } from '@documenso/lib/errors/app-error';
|
import { AppError, AppErrorCode } from '@documenso/lib/errors/app-error';
|
||||||
import { extractRequestMetadata } from '@documenso/lib/universal/extract-request-metadata';
|
import { extractRequestMetadata } from '@documenso/lib/universal/extract-request-metadata';
|
||||||
|
|
||||||
|
import { setCsrfCookie } from './lib/session/session-cookies';
|
||||||
import { emailPasswordRoute } from './routes/email-password';
|
import { emailPasswordRoute } from './routes/email-password';
|
||||||
import { googleRoute } from './routes/google';
|
import { googleRoute } from './routes/google';
|
||||||
import { passkeyRoute } from './routes/passkey';
|
import { passkeyRoute } from './routes/passkey';
|
||||||
@ -16,8 +18,28 @@ import type { HonoAuthContext } from './types/context';
|
|||||||
export const auth = new Hono<HonoAuthContext>()
|
export const auth = new Hono<HonoAuthContext>()
|
||||||
.use(async (c, next) => {
|
.use(async (c, next) => {
|
||||||
c.set('requestMetadata', extractRequestMetadata(c.req.raw));
|
c.set('requestMetadata', extractRequestMetadata(c.req.raw));
|
||||||
|
|
||||||
|
// Todo: Maybe use auth URL.
|
||||||
|
const validOrigin = new URL(NEXT_PUBLIC_WEBAPP_URL()).origin;
|
||||||
|
const headerOrigin = c.req.header('Origin');
|
||||||
|
|
||||||
|
if (headerOrigin && headerOrigin !== validOrigin) {
|
||||||
|
return c.json(
|
||||||
|
{
|
||||||
|
message: 'Forbidden',
|
||||||
|
statusCode: 403,
|
||||||
|
},
|
||||||
|
403,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
await next();
|
await next();
|
||||||
})
|
})
|
||||||
|
.get('/csrf', async (c) => {
|
||||||
|
const csrfToken = await setCsrfCookie(c);
|
||||||
|
|
||||||
|
return c.json({ csrfToken });
|
||||||
|
})
|
||||||
.route('/', sessionRoute)
|
.route('/', sessionRoute)
|
||||||
.route('/', signOutRoute)
|
.route('/', signOutRoute)
|
||||||
.route('/email-password', emailPasswordRoute)
|
.route('/email-password', emailPasswordRoute)
|
||||||
|
|||||||
@ -6,6 +6,8 @@ import { useSecureCookies } from '@documenso/lib/constants/auth';
|
|||||||
import { appLog } from '@documenso/lib/utils/debugger';
|
import { appLog } from '@documenso/lib/utils/debugger';
|
||||||
import { env } from '@documenso/lib/utils/env';
|
import { env } from '@documenso/lib/utils/env';
|
||||||
|
|
||||||
|
import { generateSessionToken } from './session';
|
||||||
|
|
||||||
export const sessionCookieName = 'sessionId';
|
export const sessionCookieName = 'sessionId';
|
||||||
|
|
||||||
const getAuthSecret = () => {
|
const getAuthSecret = () => {
|
||||||
@ -30,7 +32,7 @@ const getAuthDomain = () => {
|
|||||||
export const sessionCookieOptions = {
|
export const sessionCookieOptions = {
|
||||||
httpOnly: true,
|
httpOnly: true,
|
||||||
path: '/',
|
path: '/',
|
||||||
sameSite: useSecureCookies ? 'none' : 'lax',
|
sameSite: useSecureCookies ? 'none' : 'lax', // Todo: This feels wrong?
|
||||||
secure: useSecureCookies,
|
secure: useSecureCookies,
|
||||||
domain: getAuthDomain(),
|
domain: getAuthDomain(),
|
||||||
// Todo: Max age for specific auth cookies.
|
// Todo: Max age for specific auth cookies.
|
||||||
@ -89,3 +91,23 @@ export const setSessionCookie = async (c: Context, sessionToken: string) => {
|
|||||||
export const deleteSessionCookie = (c: Context) => {
|
export const deleteSessionCookie = (c: Context) => {
|
||||||
deleteCookie(c, sessionCookieName, sessionCookieOptions);
|
deleteCookie(c, sessionCookieName, sessionCookieOptions);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
export const getCsrfCookie = async (c: Context) => {
|
||||||
|
const csrfToken = await getSignedCookie(c, getAuthSecret(), 'csrfToken');
|
||||||
|
|
||||||
|
return csrfToken || null;
|
||||||
|
};
|
||||||
|
|
||||||
|
export const setCsrfCookie = async (c: Context) => {
|
||||||
|
const csrfToken = generateSessionToken();
|
||||||
|
|
||||||
|
await setSignedCookie(c, 'csrfToken', csrfToken, getAuthSecret(), {
|
||||||
|
...sessionCookieOptions,
|
||||||
|
|
||||||
|
// Explicity set to undefined for session lived cookie.
|
||||||
|
expires: undefined,
|
||||||
|
maxAge: undefined,
|
||||||
|
});
|
||||||
|
|
||||||
|
return csrfToken;
|
||||||
|
};
|
||||||
|
|||||||
@ -25,6 +25,7 @@ import { prisma } from '@documenso/prisma';
|
|||||||
import { UserSecurityAuditLogType } from '@documenso/prisma/client';
|
import { UserSecurityAuditLogType } from '@documenso/prisma/client';
|
||||||
|
|
||||||
import { AuthenticationErrorCode } from '../lib/errors/error-codes';
|
import { AuthenticationErrorCode } from '../lib/errors/error-codes';
|
||||||
|
import { getCsrfCookie } from '../lib/session/session-cookies';
|
||||||
import { onAuthorize } from '../lib/utils/authorizer';
|
import { onAuthorize } from '../lib/utils/authorizer';
|
||||||
import { getRequiredSession, getSession } from '../lib/utils/get-session';
|
import { getRequiredSession, getSession } from '../lib/utils/get-session';
|
||||||
import type { HonoAuthContext } from '../types/context';
|
import type { HonoAuthContext } from '../types/context';
|
||||||
@ -45,7 +46,16 @@ export const emailPasswordRoute = new Hono<HonoAuthContext>()
|
|||||||
.post('/authorize', sValidator('json', ZSignInSchema), async (c) => {
|
.post('/authorize', sValidator('json', ZSignInSchema), async (c) => {
|
||||||
const requestMetadata = c.get('requestMetadata');
|
const requestMetadata = c.get('requestMetadata');
|
||||||
|
|
||||||
const { email, password, totpCode, backupCode } = c.req.valid('json');
|
const { email, password, totpCode, backupCode, csrfToken } = c.req.valid('json');
|
||||||
|
|
||||||
|
const csrfCookieToken = await getCsrfCookie(c);
|
||||||
|
|
||||||
|
// Todo: Add logging here.
|
||||||
|
if (csrfToken !== csrfCookieToken || !csrfCookieToken) {
|
||||||
|
throw new AppError(AuthenticationErrorCode.InvalidRequest, {
|
||||||
|
message: 'Invalid CSRF token',
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
const user = await prisma.user.findFirst({
|
const user = await prisma.user.findFirst({
|
||||||
where: {
|
where: {
|
||||||
|
|||||||
@ -10,6 +10,7 @@ export const ZSignInSchema = z.object({
|
|||||||
password: ZCurrentPasswordSchema,
|
password: ZCurrentPasswordSchema,
|
||||||
totpCode: z.string().trim().optional(),
|
totpCode: z.string().trim().optional(),
|
||||||
backupCode: z.string().trim().optional(),
|
backupCode: z.string().trim().optional(),
|
||||||
|
csrfToken: z.string().trim(),
|
||||||
});
|
});
|
||||||
|
|
||||||
export type TSignInSchema = z.infer<typeof ZSignInSchema>;
|
export type TSignInSchema = z.infer<typeof ZSignInSchema>;
|
||||||
|
|||||||
Reference in New Issue
Block a user