Files
Anik Dhabal BabuGitHubDevin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
27820ce897 feat: auto-accept team invitations for existing users (#24091)
* feat: auto-accept team invitations for existing users

- Change email button text from 'View Invitation' to 'Accept Invite'
- Implement auto-accept flow when clicking email CTA
- Update TeamService.inviteMemberByToken to support auto-acceptance
- Add new autoAcceptInvite tRPC endpoint for handling auto-acceptance
- Update invitation link generation to include autoAccept parameter
- Handle both team and organization invitation scenarios
- Maintain payment/billing flow integration with TeamBilling.updateQuantity
- Preserve backward compatibility with existing manual flow
- Update all locale files with new 'Accept Invite' button text

Co-Authored-By: [email protected] <[email protected]>

* revert: locale changes except English

- Keep only English 'Accept Invite' translation
- Revert all other locale files to original 'View Invitation' translations
- Maintain core auto-accept invitation functionality

Co-Authored-By: [email protected] <[email protected]>

* simplify: remove autoAccept parameter and make auto-acceptance default

- Remove autoAccept parameter from TeamService.inviteMemberByToken
- Always auto-accept invitations for existing users clicking email links
- Remove autoAccept logic from teams server-page.tsx
- Remove autoAccept=true from invitation URLs
- Delete autoAcceptInvite handler and schema files
- Remove autoAcceptInvite endpoint from tRPC router
- Simplify invitation flow to match new user pattern

Co-Authored-By: [email protected] <[email protected]>

* test: update teamService test to expect auto-accepted memberships

- Change expectation from accepted: false to accepted: true
- Update test description to reflect auto-accept behavior
- Fix TypeScript type casting to use Pick<TeamRepository, 'deleteById'>
- Aligns with new default auto-acceptance for team invitations

Co-Authored-By: [email protected] <[email protected]>

* update

* Update utils.ts

* fix type error

* delete token

* add prisma transaction

* update

* update param

* test: fix mock objects in teamService tests with realistic data

- Fix duplicate property assignments in mock user objects
- Use proper email format ([email protected]) for email fields
- Use proper username format (testuser) for username fields
- Fix logic error in acceptInvitationByToken (|| to &&)
- Add autoAccept parameter to resendInvitation.handler.ts
- All 16 tests passing with proper TypeScript types

Co-Authored-By: [email protected] <[email protected]>

* test: add e2e tests for team invitation auto-accept flow

- Add test for existing user auto-accepting team invitation via email link
- Add test for error handling when wrong user tries to use invitation link
- Verify proper user identity validation and database state changes
- Follow existing e2e test patterns with browser context isolation
- Fix ESLint warnings: replace conditional with assertion and remove unused browser parameter

Co-Authored-By: [email protected] <[email protected]>

* fix

* fix

* fix: update team owner creation in e2e tests to include proper names

- Fix email subject mismatch in auto-accept invitation tests
- Team owners now created with explicit names instead of undefined
- Matches pattern used in other working team invitation tests

Co-Authored-By: [email protected] <[email protected]>

* fix: update organization invitation test helper to match new auto-accept link format

- Change expectExistingUserToBeInvitedToOrganization to look for 'teams?token' instead of 'settings/team'
- Fixes 'Invite link not found' error in organization booking e2e test
- Aligns with auto-accept invitation URL changes that use /teams?token= format
- Fix eslint disable comment for playwright rule

Co-Authored-By: [email protected] <[email protected]>

* address coderrabit review

* fix failing test

* addressed review

---------

Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
2025-09-30 13:07:21 +00:00

43 lines
1.7 KiB
TypeScript

import { ShellMainAppDir } from "app/(use-page-wrapper)/(main-nav)/ShellMainAppDir";
import type { PageProps as ServerPageProps } from "app/_types";
import { _generateMetadata, getTranslate } from "app/_utils";
import { cookies, headers } from "next/headers";
import { redirect } from "next/navigation";
import { getServerSession } from "@calcom/features/auth/lib/getServerSession";
import { buildLegacyRequest } from "@lib/buildLegacyCtx";
import { ServerTeamsListing } from "./server-page";
export const generateMetadata = async () =>
await _generateMetadata(
(t) => t("teams"),
(t) => t("create_manage_teams_collaborative"),
undefined,
undefined,
"/teams"
);
const ServerPage = async ({ searchParams: _searchParams }: ServerPageProps) => {
const session = await getServerSession({ req: buildLegacyRequest(await headers(), await cookies()) });
const searchParams = await _searchParams;
const token = Array.isArray(searchParams?.token) ? searchParams.token[0] : searchParams?.token;
const autoAccept = Array.isArray(searchParams?.autoAccept) ? searchParams.autoAccept[0] : searchParams?.autoAccept;
const callbackUrl = token ? `/teams?token=${encodeURIComponent(token)}${autoAccept ? `&autoAccept=${encodeURIComponent(autoAccept)}` : ''}` : null;
if (!session) {
redirect(callbackUrl ? `/auth/login?callbackUrl=${callbackUrl}` : "/auth/login");
}
const t = await getTranslate();
const { Main, CTA } = await ServerTeamsListing({ searchParams, session });
return (
<ShellMainAppDir CTA={CTA} heading={t("teams")} subtitle={t("create_manage_teams_collaborative")}>
{Main}
</ShellMainAppDir>
);
};
export default ServerPage;