#[SOLVED] How to set sessions for invited users?

11 messages · Page 1 of 1 (latest)

young flame
#

Hello!
I'm working on a new project where Teams will be a key part of the project.
I'm currently trying to invite users to a team, which according to your documentation will also create a session for the user when accepted. However, what is the point of this created session?
I see there is no way to actually authenticate the user with it, and I don't think I understand why it is created in the first place.
Does this mean, after accepting a team invite, the user will need to perform a new login?
To me this sounds quite counterintuitive.

vast condor
young flame
#

I see, how do I set this cookie to the client? It does not exist in the response as far as I can tell.
Normally, this is how I set the cookie during a auth callback

import { createAdminClient } from "@/lib/appwrite";
import { cookies } from "next/headers";
import { NextRequest } from "next/server";
import { redirect } from "next/navigation";



export async function GET(request: NextRequest) {
  const userId = request.nextUrl.searchParams.get("userId");
  const secret = request.nextUrl.searchParams.get("secret");
  

  const { account } = await createAdminClient();
  const session = await account.createSession(userId, secret);

  cookies().set("x-some-session", session.secret, {
    path: "/",
    httpOnly: true,
    sameSite: "lax",
    secure: true,
  });

  return redirect(`/elections`);
}

How do I achieve the same when accepting a team invitation?

vast condor
#

cookies are client side. when the team api call is done client side, a cookie is set

#

you might need to manually make the API call without using the SDK so that you can access the response headers and either look at the X-Fallback-Cookies or Set-Cookie header.

you may also want to submit a feature request

young flame
#

I see!
Yes im using SSR, probably should've mentioned that part, and sort of starting to regret these decisions aswell, but they've already been made. I will definitely take a look into that, thanks Steven!

young flame
#

Worked like a charm, Steven! Thank you

vast condor
young flame
#

Ended up doing a fetch call instead, getting the cookie from the header.
Here's my route

export async function GET(request: NextRequest) {

  //Params from the request
  const userId = request.nextUrl.searchParams.get("userId");
  const secret = request.nextUrl.searchParams.get("secret");
  const membershipId = request.nextUrl.searchParams.get("membershipId");
  const teamId = request.nextUrl.searchParams.get("teamId");

  //Hardcoded origin for now. 
  const origin = "https://example.com"

  if (!userId || !secret || !membershipId || !teamId) {
    return redirect('/auth/login?error=invalid_parameters')
  }

  try {

    //Update the membership without the SDK to access the cookie
    const response = await fetch(
      `${APPWRITE_ENDPOINT}/teams/${teamId}/memberships/${membershipId}/status`,
      {
        method: 'PATCH',
        headers: {
          'Content-Type': 'application/json',
          'X-Appwrite-Project': PROJECT_ID,
          'X-Appwrite-Key': API_KEY,
        },
        body: JSON.stringify({
          userId,
          secret,
        }),
      }
    );

    if (!response.ok) {
      console.error('Failed to accept invitation:', await response.text());
      return redirect('/auth/login?error=invitation_failed')
    }

    // Create response with redirect
    const redirectResponse = NextResponse.redirect(origin)

    // Extract cookies from response headers
    const setCookieHeader = response.headers.get('Set-Cookie');
    const fallbackCookies = response.headers.get('X-Fallback-Cookies');

    if (setCookieHeader) {
      // Parse and set the cookies from Set-Cookie header
      const cookiesList = setCookieHeader.split(',').map(cookie => cookie.trim());
      for (const cookieStr of cookiesList) {
        // Extract the cookie name and value
        const [cookiePart] = cookieStr.split(';');
        const [name, value] = cookiePart.split('=');
        
        // Use mapped name to ensure correct cookie name
        const mappedName = COOKIE_NAME_MAP[name] || name;
        
        redirectResponse.cookies.set(mappedName, value, {
          path: "/",
          httpOnly: true,
          sameSite: "lax",
          secure: true,
        });
      }
    }
    return redirectResponse;
  } catch (error) {
    console.error('Error handling team invitation:', error);
    return NextResponse.redirect(new URL('/auth/login?error=unexpected_error', origin));
  }
}