fix: Add option as to whether state cookie is considered for team context (#9831)

* fix: Do not consider host in cookies state unless its a workspace subdomain

* fix: Add option as to whether state cookie is considered in team context
This commit is contained in:
Tom Moor
2025-08-04 19:50:32 -04:00
committed by GitHub
parent 2f418e7c2e
commit 8dc6bcba22
4 changed files with 27 additions and 7 deletions

View File

@@ -568,7 +568,9 @@ router.post(
const { id, shareId } = ctx.input.body;
const { user } = ctx.state.auth;
const apiVersion = getAPIVersion(ctx);
const teamFromCtx = await getTeamFromContext(ctx);
const teamFromCtx = await getTeamFromContext(ctx, {
includeStateCookie: false,
});
const { document, share, collection } = await documentLoader({
id,
shareId,
@@ -1027,7 +1029,9 @@ router.post(
let isPublic = false;
if (shareId) {
const teamFromCtx = await getTeamFromContext(ctx);
const teamFromCtx = await getTeamFromContext(ctx, {
includeStateCookie: false,
});
const result = await loadPublicShare({
id: shareId,
teamId: teamFromCtx?.id,

View File

@@ -36,7 +36,9 @@ router.post(
async (ctx: APIContext<T.SharesInfoReq>) => {
const { id, collectionId, documentId } = ctx.input.body;
const { user } = ctx.state.auth;
const teamFromCtx = await getTeamFromContext(ctx);
const teamFromCtx = await getTeamFromContext(ctx, {
includeStateCookie: false,
});
// only public link loads will send "id".
if (id) {
@@ -371,7 +373,7 @@ router.get(
validate(T.SharesSitemapSchema),
async (ctx: APIContext<T.SharesSitemapReq>) => {
const { id } = ctx.input.query;
const team = await getTeamFromContext(ctx);
const team = await getTeamFromContext(ctx, { includeStateCookie: false });
const { share, sharedTree } = await loadPublicShare({
id,

View File

@@ -152,7 +152,7 @@ export const renderShare = async (ctx: Context, next: Next) => {
let analytics: Integration<IntegrationType.Analytics>[] = [];
try {
team = await getTeamFromContext(ctx);
team = await getTeamFromContext(ctx, { includeStateCookie: false });
const result = await loadPublicShare({
id: shareId,
collectionId: collectionSlug,

View File

@@ -131,10 +131,24 @@ export function getClientFromContext(ctx: Context): Client {
return client === Client.Desktop ? Client.Desktop : Client.Web;
}
export async function getTeamFromContext(ctx: Context) {
type TeamFromContextOptions = {
/**
* Whether to consider the state cookie in the context when determining the team.
* If true, the state cookie will be parsed to determine the host and infer the team
* this should only be used in the authentication process.
*/
includeStateCookie?: boolean;
};
export async function getTeamFromContext(
ctx: Context,
options: TeamFromContextOptions = { includeStateCookie: true }
) {
// "domain" is the domain the user came from when attempting auth
// we use it to infer the team they intend on signing into
const state = ctx.cookies.get("state");
const state = options.includeStateCookie
? ctx.cookies.get("state")
: undefined;
const host = state ? parseState(state).host : ctx.hostname;
const domain = parseDomain(host);