Refactor login/logout mutations a smidge

I decided that `setAuthToken` was the more appropriate server-level API, and that letting the login/logout mutations engage with the auth library made more sense to me!
This commit is contained in:
Emi Matchu 2022-08-26 16:05:11 -07:00
parent 39852c8297
commit 9982cbf93d
2 changed files with 24 additions and 28 deletions

View file

@ -4,10 +4,7 @@ import { getUserIdFromToken as getUserIdFromTokenViaAuth0 } from "./auth";
import connectToDb from "./db"; import connectToDb from "./db";
import buildLoaders from "./loaders"; import buildLoaders from "./loaders";
import { plugin as cacheControlPluginFork } from "./lib/apollo-cache-control-fork"; import { plugin as cacheControlPluginFork } from "./lib/apollo-cache-control-fork";
import { import { getUserIdFromToken as getUserIdFromTokenViaDb } from "./auth-by-db";
getAuthToken,
getUserIdFromToken as getUserIdFromTokenViaDb,
} from "./auth-by-db";
const rootTypeDefs = gql` const rootTypeDefs = gql`
enum CacheScope { enum CacheScope {
@ -86,25 +83,22 @@ const config = {
return { return {
db, db,
currentUserId, currentUserId,
login: async (params) => { setAuthToken: (authToken) => {
const authToken = await getAuthToken(params, db); if (authToken != null) {
if (authToken == null) { // Set the auth token as a secure cookie, encoded as JSON! (We also
return null; // url-encode it, which is pretty standard for cookie-writing - to
// the extent that `req.cookies` actually decodes it automatically.)
const oneWeekFromNow = new Date();
oneWeekFromNow.setDate(oneWeekFromNow.getDate() + 7);
res.setHeader(
"Set-Cookie",
`DTIAuthToken=${encodeURIComponent(JSON.stringify(authToken))}; ` +
`Max-Age=${60 * 60 * 24 * 7}; Secure; HttpOnly; SameSite=Strict`
);
} else {
// Set a header to delete the cookie. (That is, empty and expired.)
res.setHeader("Set-Cookie", `DTIAuthToken=; Max-Age=-1`);
} }
const oneWeekFromNow = new Date();
oneWeekFromNow.setDate(oneWeekFromNow.getDate() + 7);
res.setHeader(
"Set-Cookie",
`DTIAuthToken=${encodeURIComponent(JSON.stringify(authToken))}; ` +
`Max-Age=${60 * 60 * 24 * 7}; Secure; HttpOnly; SameSite=Strict`
);
return authToken;
},
logout: async () => {
// NOTE: This function isn't actually async in practice, but we mark it
// as such for consistency with `login`!
// Set a header to delete the cookie. (That is, empty and expired.)
res.setHeader("Set-Cookie", `DTIAuthToken=; Max-Age=-1`);
}, },
...buildLoaders(db), ...buildLoaders(db),
}; };

View file

@ -1,6 +1,7 @@
import { gql } from "apollo-server"; import { gql } from "apollo-server";
import { assertSupportSecretOrThrow } from "./MutationsForSupport"; import { assertSupportSecretOrThrow } from "./MutationsForSupport";
import { getAuthToken } from "../auth-by-db";
const typeDefs = gql` const typeDefs = gql`
type User { type User {
@ -365,15 +366,16 @@ const resolvers = {
}, },
Mutation: { Mutation: {
login: async (_, { username, password }, { login }) => { login: async (_, { username, password }, { setAuthToken, db }) => {
const loginToken = await login({ username, password }); const authToken = await getAuthToken({ username, password }, db);
if (loginToken == null) { if (authToken == null) {
return null; return null;
} }
return { id: loginToken.userId }; setAuthToken(authToken);
return { id: authToken.userId };
}, },
logout: async (_, __, { currentUserId, logout }) => { logout: async (_, __, { currentUserId, setAuthToken }) => {
await logout(); setAuthToken(null);
if (currentUserId == null) { if (currentUserId == null) {
return null; return null;
} }