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.
#[SOLVED] How to set sessions for invited users?
11 messages · Page 1 of 1 (latest)
Yes, the session is for authentication. The session is in a cookie (or falls back to local storage if using the web sdk). With this session, there is no need to authenticate again
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?
oh....you have SSR...
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
either that...or you can call the users.createSession() if the team api call is successful
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!
Worked like a charm, Steven! Thank you
Which approach did you end up with?
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));
}
}