I have a problem with returning protected fields from PersonType in the login mutation.
The idea is to set the cookie or session, and then return the user with some protected fields.
Server:
const server = new ApolloServer({
schema,
context: async ({ req, res }: { req: Request; res: Response }) => {
const person = await authenticatePerson(req); //Get user from session or auth header
return {
req,
res,
person,
};
},
});
Resolver:
loginCms: {
type: PersonType,
args: { data: { type: new GraphQLNonNull(LoginCmsInput) } },
resolve: async (_, args) => {
try {
const personExists = await prisma.person.findUnique({
where: {
email: args.data.email,
},
});
//... Other checks
req.session.user = {
id: personExists.id.toString(),
personRoleSubjectId: personExists.PersonRoleSubject[0].id.toString(),
};
if (args.data.remember) {
//14 Days
req.session.cookie.maxAge = 1000 * 60 * 60 * 24 * 14;
}
return person;
} catch (error) {
throw handleCatchError(error);
}
},
},
PersonType
//...
activePersonRoleSubject: {
type: PersonRoleSubjectType,
resolve: async (parent, args, { person }) => {
try {
//Person is null because the context already resolved before the the login resolver got called, and I cannot update context
console.log("PERSON", person);
if (!person?.id) {
return null;
}
if (parent.id === person.id) {
return person.PersonRoleSubject;
}
return null;
} catch (error) {
throw handleCatchError(error);
}
},
},
//...
This works when session and cookies are already set, but it doesnt work on the first login call.
There are two solutions that I can think of:
-
Return a boolean on successful login, and then fire another query (currentPerson) to return the person with protected fields. This would work but it requires two api calls for every login.
-
Return non-protected fields on login, and then query protected fields. Still requires two api calls
Are there any better solutions to this?