all repos — caroster @ 8e2092a5f2a1eeb65b71e931389fbf10042ba57b

[Octree] Group carpool to your event https://caroster.io

backend/src/extensions/users-permissions/services/magic-link.ts (view raw)

 1import jwt from "jsonwebtoken";
 2
 3const MAGICLINK_SECRET = process.env.MAGICLINK_SECRET;
 4
 5interface MagicTokenPayload {
 6  email: string;
 7  lang: string;
 8}
 9
10export const generateMagicToken = async (email: string, lang: string) => {
11  const existingUser = await strapi.db
12    .query("plugin::users-permissions.user")
13    .findOne({
14      where: { email },
15    });
16
17  if (existingUser?.provider === "google") {
18    strapi.log.warn(
19      `User ${email} is linked to Google account. Can't login with magic link.`
20    );
21    throw new Error("GoogleAccount");
22  }
23  if (!MAGICLINK_SECRET) throw new Error("No MAGICLINK_SECRET provided");
24
25  strapi.entityService.create("api::log.log", {
26    data: { type: "AUTH_TOKEN_GENERATION", payload: { email, lang } },
27  });
28
29  return jwt.sign({ email, lang }, MAGICLINK_SECRET, { expiresIn: "20m" });
30};
31
32export const verifyMagicToken = (token: string) => {
33  try {
34    const decoded = jwt.verify(token, MAGICLINK_SECRET) as MagicTokenPayload;
35    strapi.entityService.create("api::log.log", {
36      data: {
37        type: "AUTH_TOKEN_VERIFICATION",
38        payload: { email: decoded.email, lang: decoded.lang, valid: true },
39      },
40    });
41    return decoded;
42  } catch (error) {
43    const decoded = jwt.decode(token) as MagicTokenPayload;
44    strapi.entityService.create("api::log.log", {
45      data: {
46        type: "AUTH_TOKEN_VERIFICATION",
47        payload: { email: decoded.email, lang: decoded.lang, valid: false },
48      },
49    });
50    throw new Error("Invalid token");
51  }
52};