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 ],
30 resolvers: {
31 Query: {
32 me: {
33 async resolve(_root, _args, context) {
34 const user = context.state?.user;
35 if (!user) throw new Error("Authentication requested");
36 return { id: user.id, username: user.username, profile: user };
37 },
38 },
39 },
40 Mutation: {
41 updateMe: {
42 async resolve(_root, args, context) {
43 const { data: userUpdate } = args;
44 const userId = context.state?.user?.id;
45
46 if (!userId) throw new Error("Authentication requested");
47
48 const user = await strapi
49 .plugin("users-permissions")
50 .services.user.fetch(userId, { populate: { events: true } });
51
52 if (userUpdate.password) {
53 const validPassword = await strapi
54 .plugin("users-permissions")
55 .services.user.validatePassword(
56 userUpdate.oldPassword || "",
57 user.password
58 );
59 if (!validPassword) throw new Error("Wrong password");
60 delete userUpdate.oldPassword;
61 }
62
63 const currentEvents = user.events || [];
64 const currentEventIds = currentEvents.map((event) => `${event.id}`);
65 const userUpdateEvents = userUpdate.events?.filter(
66 (eventId) => !currentEventIds.includes(eventId)
67 );
68 const updatedEvents = userUpdate.events
69 ? [...currentEvents, ...userUpdateEvents]
70 : user.events;
71
72 const updatedUser = await strapi.entityService.update(
73 "plugin::users-permissions.user",
74 user.id,
75 {
76 data: {
77 ...userUpdate,
78 events: updatedEvents,
79 },
80 }
81 );
82 const { toEntityResponse } = strapi
83 .plugin("graphql")
84 .service("format").returnTypes;
85
86 return toEntityResponse(updatedUser, {
87 args,
88 resourceUID: "plugin::users-permissions.user",
89 });
90 },
91 },
92 },
93 // Filter user fields if not for profile fetching
94 UsersPermissionsUser: {
95 vehicles: {
96 async resolve(queriedUser, args, _context, query) {
97 if (query.path.prev.key !== "profile") return null;
98
99 const user = await strapi.entityService.findOne(
100 "plugin::users-permissions.user",
101 queriedUser.id,
102 { populate: ["vehicles"] }
103 );
104 if (!user?.vehicles) return null;
105
106 const { toEntityResponseCollection } = strapi
107 .plugin("graphql")
108 .service("format").returnTypes;
109
110 return toEntityResponseCollection(user.vehicles, {
111 args,
112 resourceUID: "api::vehicle.vehicle",
113 });
114 },
115 },
116 },
117 },
118 resolversConfig: {
119 "Query.me": {
120 auth: {
121 scope: ["plugin::users-permissions.user.me"],
122 },
123 },
124 "UsersPermissionsUser.vehicles": {
125 auth: true,
126 },
127 "UsersPermissionsUser.events": {
128 auth: true,
129 policies: [checkAuthUser],
130 },
131 "UsersPermissionsUser.notifications": {
132 auth: true,
133 policies: [checkAuthUser],
134 },
135 "UsersPermissionsUser.confirmed": {
136 auth: true,
137 policies: [checkAuthUser],
138 },
139 "UsersPermissionsUser.provider": {
140 auth: true,
141 policies: [checkAuthUser],
142 },
143 "UsersPermissionsUser.newsletterConsent": {
144 auth: true,
145 policies: [checkAuthUser],
146 },
147 "UsersPermissionsUser.createdAt": {
148 auth: true,
149 policies: [checkAuthUser],
150 },
151 "UsersPermissionsUser.onboardingCreator": {
152 auth: true,
153 policies: [checkAuthUser],
154 },
155 "UsersPermissionsUser.onboardingUser": {
156 auth: true,
157 policies: [checkAuthUser],
158 },
159 },
160 }),
161];
162
163const checkAuthUser = (context) => {
164 const authUser = context.state.user;
165 return context.parent.id === authUser.id;
166};