backend/src/graphql/user/index.ts (view raw)
1export default [
2 ({ nexus, strapi }) => ({
3 types: [
4 nexus.extendType({
5 type: "UsersPermissionsMe",
6 definition(t) {
7 t.field("profile", {
8 type: "UsersPermissionsUser",
9 });
10 },
11 }),
12 nexus.extendInputType({
13 type: "UsersPermissionsUserInput",
14 definition(t) {
15 t.string("oldPassword");
16 },
17 }),
18 nexus.extendType({
19 type: "Mutation",
20 definition(t) {
21 t.field("updateMe", {
22 type: nexus.nonNull("UsersPermissionsUserEntityResponse"),
23 args: {
24 data: nexus.nonNull("UsersPermissionsUserInput"),
25 },
26 });
27 },
28 }),
29 nexus.mutationField("sendMagicLink", {
30 type: "Boolean",
31 args: {
32 email: nexus.nonNull("String"),
33 lang: "String",
34 },
35 }),
36 ],
37 resolvers: {
38 Query: {
39 me: {
40 async resolve(_root, _args, context) {
41 const user = context.state?.user;
42 if (!user) throw new Error("Authentication requested");
43 return { id: user.id, username: user.username, profile: user };
44 },
45 },
46 },
47 Mutation: {
48 updateMe: {
49 async resolve(_root, args, context) {
50 const { data: userUpdate } = args;
51 const userId = context.state?.user?.id;
52
53 if (!userId) throw new Error("Authentication requested");
54
55 const user = await strapi
56 .plugin("users-permissions")
57 .services.user.fetch(userId, { populate: { events: true } });
58
59 if (userUpdate.password) {
60 const validPassword = await strapi
61 .plugin("users-permissions")
62 .services.user.validatePassword(
63 userUpdate.oldPassword || "",
64 user.password
65 );
66 if (!validPassword) throw new Error("Wrong password");
67 delete userUpdate.oldPassword;
68 }
69
70 const currentEvents = user.events || [];
71 const currentEventIds = currentEvents.map((event) => `${event.id}`);
72 const userUpdateEvents = userUpdate.events?.filter(
73 (eventId) => !currentEventIds.includes(eventId)
74 );
75 const updatedEvents = userUpdate.events
76 ? [...currentEvents, ...userUpdateEvents]
77 : user.events;
78
79 const updatedUser = await strapi.entityService.update(
80 "plugin::users-permissions.user",
81 user.id,
82 {
83 data: {
84 ...userUpdate,
85 events: updatedEvents,
86 },
87 }
88 );
89 const { toEntityResponse } = strapi
90 .plugin("graphql")
91 .service("format").returnTypes;
92
93 return toEntityResponse(updatedUser, {
94 args,
95 resourceUID: "plugin::users-permissions.user",
96 });
97 },
98 },
99 sendMagicLink: {
100 async resolve(_root, args) {
101 const { email, lang } = args;
102 const magicToken = await strapi.services[
103 "plugin::users-permissions.user"
104 ].magicLink.generateMagicToken(email);
105 const magicLink = `${strapi.config.get(
106 "server.url"
107 )}/auth/magic-link?token=${magicToken}`;
108
109 try {
110 await strapi
111 .service("api::email.email")
112 .sendEmailNotif(email, "MagicLinkLogin", lang || "en", {
113 magicLink,
114 });
115 return true;
116 } catch (error) {
117 strapi.log.error(error);
118 return false;
119 }
120 },
121 },
122 },
123 },
124 resolversConfig: {
125 "Query.me": {
126 auth: {
127 scope: ["plugin::users-permissions.user.me"],
128 },
129 },
130 "Mutation.sendMagicLink": {
131 auth: false,
132 },
133 "UsersPermissionsUser.events": {
134 auth: true,
135 policies: [checkAuthUser],
136 },
137 "UsersPermissionsUser.notifications": {
138 auth: true,
139 policies: [checkAuthUser],
140 },
141 "UsersPermissionsUser.confirmed": {
142 auth: true,
143 policies: [checkAuthUser],
144 },
145 "UsersPermissionsUser.provider": {
146 auth: true,
147 policies: [checkAuthUser],
148 },
149 "UsersPermissionsUser.newsletterConsent": {
150 auth: true,
151 policies: [checkAuthUser],
152 },
153 "UsersPermissionsUser.createdAt": {
154 auth: true,
155 policies: [checkAuthUser],
156 },
157 "UsersPermissionsUser.onboardingCreator": {
158 auth: true,
159 policies: [checkAuthUser],
160 },
161 "UsersPermissionsUser.onboardingUser": {
162 auth: true,
163 policies: [checkAuthUser],
164 },
165 },
166 }),
167];
168
169const checkAuthUser = (context) => {
170 const authUser = context.state.user;
171 return context.parent.id === authUser.id;
172};