@webresto/graphql 1.3.7 → 1.3.8
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.gitattributes +2 -0
- package/.gitlab-ci.yml +18 -0
- package/.vscode/extensions.json +5 -0
- package/docs/actions.md +25 -0
- package/docs/authorization.md +215 -0
- package/docs/captcha.md +71 -0
- package/docs/device-id.md +30 -0
- package/docs/messages.md +10 -0
- package/docs/user.md +54 -0
- package/index.d.ts +0 -1
- package/index.js +6 -2
- package/index.ts +2 -2
- package/lib/afterHook.js +8 -0
- package/lib/afterHook.ts +9 -0
- package/lib/bindTranslations.d.ts +1 -0
- package/lib/bindTranslations.js +40 -0
- package/lib/bindTranslations.ts +39 -0
- package/lib/defaults.d.ts +1 -0
- package/lib/defaults.js +49 -10
- package/lib/defaults.ts +55 -0
- package/lib/eventHelper.d.ts +14 -5
- package/lib/eventHelper.js +28 -9
- package/lib/eventHelper.ts +41 -8
- package/lib/getRecomended.d.ts +1 -0
- package/lib/getRecomended.js +29 -0
- package/lib/getRecomended.ts +31 -0
- package/lib/graphqlHelper.d.ts +3 -4
- package/lib/graphqlHelper.js +184 -72
- package/lib/graphqlHelper.ts +329 -185
- package/lib/jwt.d.ts +10 -0
- package/lib/jwt.js +43 -0
- package/lib/jwt.ts +61 -0
- package/package.json +13 -6
- package/src/additionalResolvers.d.ts +72 -9
- package/src/additionalResolvers.js +93 -24
- package/src/additionalResolvers.ts +105 -34
- package/src/graphql.d.ts +5 -3
- package/src/graphql.js +170 -37
- package/src/graphql.ts +210 -60
- package/src/resolvers/bonusProgram.d.ts +32 -0
- package/src/resolvers/bonusProgram.js +65 -0
- package/src/resolvers/bonusProgram.ts +79 -0
- package/src/resolvers/captcha.d.ts +11 -0
- package/src/resolvers/captcha.js +19 -0
- package/src/resolvers/captcha.ts +16 -0
- package/src/resolvers/checkout.d.ts +35 -16
- package/src/resolvers/checkout.js +171 -94
- package/src/resolvers/checkout.ts +214 -104
- package/src/resolvers/dishAndModifier.js +8 -4
- package/src/resolvers/dishAndModifier.ts +4 -0
- package/src/resolvers/error.d.ts +9 -0
- package/src/resolvers/error.js +21 -0
- package/src/resolvers/error.ts +21 -0
- package/src/resolvers/menu.d.ts +9 -0
- package/src/resolvers/menu.js +12 -0
- package/src/resolvers/menu.ts +10 -0
- package/src/resolvers/order.d.ts +527 -0
- package/src/resolvers/order.js +349 -0
- package/src/resolvers/order.ts +435 -0
- package/src/resolvers/paymentMethod.js +7 -3
- package/src/resolvers/paymentMethod.ts +9 -5
- package/src/resolvers/pickupPoint.d.ts +1 -0
- package/src/resolvers/pickupPoint.js +24 -0
- package/src/resolvers/pickupPoint.ts +23 -0
- package/src/resolvers/recomended.d.ts +13 -0
- package/src/resolvers/recomended.js +80 -0
- package/src/resolvers/recomended.ts +86 -0
- package/src/resolvers/restrictions.d.ts +37 -1
- package/src/resolvers/restrictions.js +100 -15
- package/src/resolvers/restrictions.ts +106 -14
- package/src/resolvers/streets.d.ts +1 -1
- package/src/resolvers/streets.js +1 -4
- package/src/resolvers/streets.ts +1 -3
- package/src/resolvers/subscriptions.d.ts +4 -4
- package/src/resolvers/subscriptions.js +49 -12
- package/src/resolvers/subscriptions.ts +59 -14
- package/src/resolvers/telemetry.d.ts +14 -0
- package/src/resolvers/telemetry.js +25 -0
- package/src/resolvers/telemetry.ts +24 -0
- package/src/resolvers/user.d.ts +82 -0
- package/src/resolvers/user.js +416 -0
- package/src/resolvers/user.ts +621 -0
- package/src/resolvers/userLocation.d.ts +53 -0
- package/src/resolvers/userLocation.js +74 -0
- package/src/resolvers/userLocation.ts +125 -0
- package/src/resolvers/userOTPrequest.d.ts +21 -0
- package/src/resolvers/userOTPrequest.js +57 -0
- package/src/resolvers/userOTPrequest.ts +75 -0
- package/test/e2e_helper.js +157 -0
- package/test/e2e_helper.ts +212 -0
- package/test/fixture/config/i18n.js +7 -20
- package/test/fixture/config/locales/de.json +1 -0
- package/test/fixture/config/locales/en.json +10 -0
- package/test/fixture/config/locales/es.json +3 -0
- package/test/fixture/config/locales/fr.json +1 -0
- package/test/fixture/config/log.js +1 -1
- package/test/fixture/package.json +5 -6
- package/test/fixture/patches/rttc+10.0.1.patch +17 -0
- package/test/integration/captcha.test.js +20 -0
- package/test/integration/captcha.test.ts +25 -0
- package/test/integration/dish.test.js +35 -0
- package/test/integration/dish.test.ts +43 -0
- package/test/integration/graphql.test.js +5 -2
- package/test/integration/graphql.test.ts +2 -4
- package/test/integration/images.test.js +35 -0
- package/test/integration/images.test.ts +40 -0
- package/test/integration/locale.test.js +26 -0
- package/test/integration/locale.test.ts +32 -0
- package/test/integration/order.test.js +56 -43
- package/test/integration/order.test.ts +59 -59
- package/test/integration/subscriptions.test.js +136 -0
- package/test/integration/subscriptions.test.ts +162 -0
- package/test/integration/user.test.js +249 -0
- package/test/integration/user.test.ts +299 -0
- package/test/unit/first.test.js +4 -2
- package/test/unit/first.test.ts +1 -1
- package/test/unit/get-recomended.test.js +56 -0
- package/test/unit/get-recomended.test.ts +63 -0
- package/translations/de.json +2 -0
- package/translations/en.json +3 -0
- package/translations/es.json +3 -0
- package/translations/fr.json +2 -0
- package/translations/ru.json +36 -0
- package/tsconfig.json +20 -5
- package/types/global.d.ts +30 -0
- package/types/global.js +2 -0
- package/types/global.ts +31 -0
- package/types/primitives.d.ts +19 -0
- package/types/references.d.ts +1 -0
- package/types/restoGraphQLConfig.d.ts +13 -0
- package/lib/afterHook.ts___graphql-transport-ws +0 -138
- package/lib/afterHook.ts___graphql-ws +0 -133
- package/lib/errorWrapper.d.ts +0 -4
- package/lib/errorWrapper.js +0 -13
- package/lib/errorWrapper.ts +0 -12
- package/notes.md +0 -1976
- package/src/resolvers/cart.d.ts +0 -343
- package/src/resolvers/cart.js +0 -196
- package/src/resolvers/cart.ts +0 -278
- package/test/fixture/config/connections.js +0 -9
- package/test/integration/sails_not_crash.test.js +0 -3
- package/test/integration/sails_not_crash.test.ts +0 -3
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
const graphqlHelper_1 = require("../../lib/graphqlHelper");
|
|
4
|
+
graphqlHelper_1.default.addType(`#graphql
|
|
5
|
+
type Telemetry {
|
|
6
|
+
"System uptime in seconds"
|
|
7
|
+
uptime: Float
|
|
8
|
+
i18n: String
|
|
9
|
+
locale: String
|
|
10
|
+
}
|
|
11
|
+
`);
|
|
12
|
+
exports.default = {
|
|
13
|
+
Query: {
|
|
14
|
+
telemetry: {
|
|
15
|
+
def: 'telemetry: Telemetry',
|
|
16
|
+
fn: () => ({})
|
|
17
|
+
}
|
|
18
|
+
},
|
|
19
|
+
Telemetry: {
|
|
20
|
+
uptime: () => process.uptime(),
|
|
21
|
+
//@ts-ignore
|
|
22
|
+
i18n: (parent, args, context, info) => context.i18n.__('Status here'),
|
|
23
|
+
locale: (parent, args, context, info) => context.connectionParams.locale
|
|
24
|
+
}
|
|
25
|
+
};
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import graphqlHelper from "../../lib/graphqlHelper";
|
|
2
|
+
graphqlHelper.addType(`#graphql
|
|
3
|
+
type Telemetry {
|
|
4
|
+
"System uptime in seconds"
|
|
5
|
+
uptime: Float
|
|
6
|
+
i18n: String
|
|
7
|
+
locale: String
|
|
8
|
+
}
|
|
9
|
+
`);
|
|
10
|
+
|
|
11
|
+
export default {
|
|
12
|
+
Query: {
|
|
13
|
+
telemetry: {
|
|
14
|
+
def: 'telemetry: Telemetry',
|
|
15
|
+
fn: () => ({})
|
|
16
|
+
}
|
|
17
|
+
},
|
|
18
|
+
Telemetry: {
|
|
19
|
+
uptime: () => process.uptime(),
|
|
20
|
+
//@ts-ignore
|
|
21
|
+
i18n: (parent, args, context, info) => context.i18n.__('Status here'),
|
|
22
|
+
locale: (parent, args, context, info) => context.connectionParams.locale
|
|
23
|
+
}
|
|
24
|
+
}
|
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
import { Phone } from "@webresto/core/models/User";
|
|
2
|
+
import User from "@webresto/core/models/User";
|
|
3
|
+
import { ResolvedCaptcha } from "@webresto/core/adapters/captcha/CaptchaAdapter";
|
|
4
|
+
import { Response } from "../../types/primitives";
|
|
5
|
+
interface UserResponse extends Response {
|
|
6
|
+
user: User | undefined;
|
|
7
|
+
}
|
|
8
|
+
interface InputUser {
|
|
9
|
+
firstName: string;
|
|
10
|
+
lastName: string;
|
|
11
|
+
birthday: string;
|
|
12
|
+
customData: {
|
|
13
|
+
[key: string]: string | boolean | number;
|
|
14
|
+
};
|
|
15
|
+
customFields: {
|
|
16
|
+
[key: string]: string | boolean | number;
|
|
17
|
+
};
|
|
18
|
+
}
|
|
19
|
+
type RegistrationPayload = {
|
|
20
|
+
login: string;
|
|
21
|
+
phone: Phone;
|
|
22
|
+
password: string;
|
|
23
|
+
otp: string;
|
|
24
|
+
firstName: string;
|
|
25
|
+
lastName: string;
|
|
26
|
+
customFields: {
|
|
27
|
+
[key: string]: string | boolean | number;
|
|
28
|
+
};
|
|
29
|
+
captcha: ResolvedCaptcha;
|
|
30
|
+
};
|
|
31
|
+
declare const _default: {
|
|
32
|
+
Mutation: {
|
|
33
|
+
login: {
|
|
34
|
+
def: string;
|
|
35
|
+
fn: (parent: any, payload: any, context: any, info: any) => Promise<UserResponse>;
|
|
36
|
+
};
|
|
37
|
+
restorePassword: {
|
|
38
|
+
def: string;
|
|
39
|
+
fn: (parent: any, payload: any, context: any) => Promise<UserResponse>;
|
|
40
|
+
};
|
|
41
|
+
registration: {
|
|
42
|
+
def: string;
|
|
43
|
+
fn: (parent: any, payload: RegistrationPayload, context: any, info: any) => Promise<UserResponse>;
|
|
44
|
+
};
|
|
45
|
+
logout: {
|
|
46
|
+
def: string;
|
|
47
|
+
fn: (parent: any, payload: {
|
|
48
|
+
deviceId: any;
|
|
49
|
+
}, context: {
|
|
50
|
+
connectionParams: {
|
|
51
|
+
authorization: string;
|
|
52
|
+
};
|
|
53
|
+
i18n: any;
|
|
54
|
+
}) => Promise<Response>;
|
|
55
|
+
};
|
|
56
|
+
logoutFromAllDevices: {
|
|
57
|
+
def: string;
|
|
58
|
+
fn: (parent: any, payload: any, context: any) => Promise<Response>;
|
|
59
|
+
};
|
|
60
|
+
favoriteDish: {
|
|
61
|
+
def: string;
|
|
62
|
+
fn: (parent: any, payload: {
|
|
63
|
+
dishId: string;
|
|
64
|
+
}, context: {
|
|
65
|
+
connectionParams: {
|
|
66
|
+
authorization: string;
|
|
67
|
+
};
|
|
68
|
+
}) => Promise<boolean>;
|
|
69
|
+
};
|
|
70
|
+
userUpdate: {
|
|
71
|
+
def: string;
|
|
72
|
+
fn: (parent: any, payload: {
|
|
73
|
+
user: InputUser;
|
|
74
|
+
}, context: any) => Promise<UserResponse>;
|
|
75
|
+
};
|
|
76
|
+
userDelete: {
|
|
77
|
+
def: string;
|
|
78
|
+
fn: (parent: any, payload: any, context: any, info: any) => Promise<Response>;
|
|
79
|
+
};
|
|
80
|
+
};
|
|
81
|
+
};
|
|
82
|
+
export default _default;
|
|
@@ -0,0 +1,416 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
// const userAuth = sails.config.restographql.authService;
|
|
4
|
+
const jwt_1 = require("../../lib/jwt");
|
|
5
|
+
const adapters_1 = require("@webresto/core/adapters");
|
|
6
|
+
let captchaAdapter = adapters_1.Captcha.getAdapter();
|
|
7
|
+
const graphqlHelper_1 = require("../../lib/graphqlHelper");
|
|
8
|
+
graphqlHelper_1.default.addType(`#graphql
|
|
9
|
+
type UserResponse {
|
|
10
|
+
user: User
|
|
11
|
+
message: Message
|
|
12
|
+
action: Action
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
input InputUser {
|
|
16
|
+
firstName: String
|
|
17
|
+
lastName: String
|
|
18
|
+
birthday: String
|
|
19
|
+
customData: Json
|
|
20
|
+
customFields: Json
|
|
21
|
+
}
|
|
22
|
+
`);
|
|
23
|
+
exports.default = {
|
|
24
|
+
Mutation: {
|
|
25
|
+
login: {
|
|
26
|
+
def: `#graphql
|
|
27
|
+
""" login method """
|
|
28
|
+
login(
|
|
29
|
+
login: String!,
|
|
30
|
+
|
|
31
|
+
"(required when login field is phone)"
|
|
32
|
+
phone: InputPhone,
|
|
33
|
+
|
|
34
|
+
"(only when passwordPolicy is required )"
|
|
35
|
+
password: String,
|
|
36
|
+
|
|
37
|
+
"(from otpRequest)"
|
|
38
|
+
otp: String,
|
|
39
|
+
|
|
40
|
+
"(solved captcha for label 'quickAccessByOTP:%login%')"
|
|
41
|
+
captcha: Captcha!
|
|
42
|
+
): UserResponse`,
|
|
43
|
+
fn: async (parent, payload, context, info) => {
|
|
44
|
+
// TODO: this is copied from restrictions need make it from one place
|
|
45
|
+
if (!(await captchaAdapter).check(payload.captcha, `login:${payload.login}`))
|
|
46
|
+
throw `bad captcha`;
|
|
47
|
+
// Define password policy
|
|
48
|
+
let passwordPolicy = (await Settings.get("PASSWORD_POLICY"));
|
|
49
|
+
if (!passwordPolicy)
|
|
50
|
+
passwordPolicy = "from_otp";
|
|
51
|
+
let loginOTPRequired = await Settings.get("LOGIN_OTP_REQUIRED");
|
|
52
|
+
if (!loginOTPRequired)
|
|
53
|
+
loginOTPRequired = false;
|
|
54
|
+
let loginField = await Settings.get("LOGIN_FIELD");
|
|
55
|
+
if (!loginField)
|
|
56
|
+
loginField = "phone";
|
|
57
|
+
if (passwordPolicy === "required" && !payload.password) {
|
|
58
|
+
throw `password is required`;
|
|
59
|
+
}
|
|
60
|
+
if (loginOTPRequired && !payload.otp) {
|
|
61
|
+
throw `OTP is required`;
|
|
62
|
+
}
|
|
63
|
+
// It shoul have or Password or OTP at one time
|
|
64
|
+
if (!payload.otp && !payload.password) {
|
|
65
|
+
throw `or Password or OTP required`;
|
|
66
|
+
}
|
|
67
|
+
if (!context.connectionParams.deviceId) {
|
|
68
|
+
throw `Missed deviceId`;
|
|
69
|
+
}
|
|
70
|
+
// Check phone TODO: move in User
|
|
71
|
+
if ((await Settings.get("LOGIN_FIELD")) === undefined ||
|
|
72
|
+
(await Settings.get("LOGIN_FIELD")) === "phone") {
|
|
73
|
+
if (!payload.phone) {
|
|
74
|
+
throw `Phone is required, when login field is phone`;
|
|
75
|
+
}
|
|
76
|
+
else {
|
|
77
|
+
let genLogin = (payload.phone.code +
|
|
78
|
+
payload.phone.number +
|
|
79
|
+
payload.phone.additionalNumber).replace(/\D/g, "");
|
|
80
|
+
if (genLogin !== payload.login) {
|
|
81
|
+
throw `Login is: js (payload.phone.code+payload.phone.number+payload.phone.additionalNumber).replace(/\D/g, '')`;
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
let userDevice = await User.login(payload.login, payload.phone, context.connectionParams.deviceId, "DEVICE NAME", payload.password, payload.otp, context.connectionParams["user-agent"], "IP_");
|
|
86
|
+
let authData = {
|
|
87
|
+
userId: userDevice.user,
|
|
88
|
+
deviceId: userDevice.id,
|
|
89
|
+
sessionId: userDevice.sessionId,
|
|
90
|
+
};
|
|
91
|
+
const JWTtoken = await jwt_1.JWTAuth.sign(authData);
|
|
92
|
+
let message = {
|
|
93
|
+
deviceId: context.connectionParams.deviceId,
|
|
94
|
+
title: context.i18n.__("Success"),
|
|
95
|
+
type: "info",
|
|
96
|
+
message: context.i18n.__("Authorization"),
|
|
97
|
+
};
|
|
98
|
+
let user = await User.findOne({ id: userDevice.user });
|
|
99
|
+
context.connectionParams.authorization = JWTtoken;
|
|
100
|
+
let action = {
|
|
101
|
+
deviceId: context.connectionParams.deviceId,
|
|
102
|
+
type: "Authorization",
|
|
103
|
+
data: {
|
|
104
|
+
token: JWTtoken,
|
|
105
|
+
},
|
|
106
|
+
};
|
|
107
|
+
// Here should be Emmiter for midificate Action And Message
|
|
108
|
+
return {
|
|
109
|
+
user: user,
|
|
110
|
+
message: message,
|
|
111
|
+
action: action,
|
|
112
|
+
};
|
|
113
|
+
},
|
|
114
|
+
},
|
|
115
|
+
restorePassword: {
|
|
116
|
+
def: `#graphql
|
|
117
|
+
""" Password restore method """
|
|
118
|
+
restorePassword(
|
|
119
|
+
login: String!,
|
|
120
|
+
|
|
121
|
+
"(required when login field is phone)"
|
|
122
|
+
phone: InputPhone,
|
|
123
|
+
|
|
124
|
+
password: String!,
|
|
125
|
+
|
|
126
|
+
"(from otpRequest)"
|
|
127
|
+
otp: String!,
|
|
128
|
+
|
|
129
|
+
"(solved captcha for label 'quickAccessByOTP:%login%')"
|
|
130
|
+
captcha: Captcha!
|
|
131
|
+
): UserResponse`,
|
|
132
|
+
fn: async (parent, payload, context) => {
|
|
133
|
+
if (!context.connectionParams.deviceId) {
|
|
134
|
+
throw `Missed deviceId`;
|
|
135
|
+
}
|
|
136
|
+
// Check password policy
|
|
137
|
+
let passwordPolicy = (await Settings.get("PASSWORD_POLICY"));
|
|
138
|
+
if (!passwordPolicy)
|
|
139
|
+
passwordPolicy = "from_otp";
|
|
140
|
+
// It shoul have or Password or OTP at one time
|
|
141
|
+
if (!payload.otp || !payload.password) {
|
|
142
|
+
throw `Password and OTP required`;
|
|
143
|
+
}
|
|
144
|
+
let userDevice;
|
|
145
|
+
let user = await User.findOne({ login: payload.login });
|
|
146
|
+
if (user && user.verified) {
|
|
147
|
+
userDevice = await User.login(payload.login, payload.phone, context.connectionParams.deviceId, "DEVICE NAME", null, payload.otp, context.connectionParams["user-agent"], "0.0.0.0");
|
|
148
|
+
await User.setPassword(user.id, payload.password, null, true, null);
|
|
149
|
+
}
|
|
150
|
+
else {
|
|
151
|
+
return {
|
|
152
|
+
user: null,
|
|
153
|
+
message: {
|
|
154
|
+
deviceId: context.connectionParams.deviceId,
|
|
155
|
+
title: context.i18n.__("User not found"),
|
|
156
|
+
type: "error",
|
|
157
|
+
message: context.i18n.__("Check login please"),
|
|
158
|
+
},
|
|
159
|
+
action: null,
|
|
160
|
+
};
|
|
161
|
+
}
|
|
162
|
+
let authData = {
|
|
163
|
+
userId: userDevice.user,
|
|
164
|
+
deviceId: userDevice.id,
|
|
165
|
+
sessionId: userDevice.sessionId,
|
|
166
|
+
};
|
|
167
|
+
const JWTtoken = await jwt_1.JWTAuth.sign(authData);
|
|
168
|
+
let message = {
|
|
169
|
+
deviceId: context.connectionParams.deviceId,
|
|
170
|
+
title: context.i18n.__("Success"),
|
|
171
|
+
type: "info",
|
|
172
|
+
message: context.i18n.__("Password was cahanged"),
|
|
173
|
+
};
|
|
174
|
+
let action = {
|
|
175
|
+
deviceId: context.connectionParams.deviceId,
|
|
176
|
+
type: "Authorization",
|
|
177
|
+
data: {
|
|
178
|
+
token: JWTtoken,
|
|
179
|
+
},
|
|
180
|
+
};
|
|
181
|
+
// Here should be Emmiter for midificate Action And Message
|
|
182
|
+
return {
|
|
183
|
+
user: user,
|
|
184
|
+
message: message,
|
|
185
|
+
action: action,
|
|
186
|
+
};
|
|
187
|
+
},
|
|
188
|
+
},
|
|
189
|
+
registration: {
|
|
190
|
+
def: `#graphql
|
|
191
|
+
registration(
|
|
192
|
+
|
|
193
|
+
"loginField from UserRestrictions, When (UserRestrictions.loginField=phone) you must send concatenate [otp+number] (only digits)"
|
|
194
|
+
login: String!,
|
|
195
|
+
|
|
196
|
+
"required when loginField=phone, it will checks with login field"
|
|
197
|
+
phone: InputPhone
|
|
198
|
+
|
|
199
|
+
password: String,
|
|
200
|
+
|
|
201
|
+
"otp from otpRequest"
|
|
202
|
+
otp: String!
|
|
203
|
+
|
|
204
|
+
firstName: String,
|
|
205
|
+
lastName: String,
|
|
206
|
+
|
|
207
|
+
"Is object {} with all required fields from UserRestrictions.customFields. Is required if custom required fields was defined"
|
|
208
|
+
customFields: Json,
|
|
209
|
+
|
|
210
|
+
"Solved captcha for label 'registration:%login%'"
|
|
211
|
+
captcha: Captcha!
|
|
212
|
+
): UserResponse`,
|
|
213
|
+
fn: async (parent, payload, context, info) => {
|
|
214
|
+
if (!context.connectionParams.deviceId) {
|
|
215
|
+
throw `Missed deviceId`;
|
|
216
|
+
}
|
|
217
|
+
try {
|
|
218
|
+
if (!(await captchaAdapter).check(payload.captcha, `registration:${payload.login}`))
|
|
219
|
+
throw `bad captcha`;
|
|
220
|
+
if (!payload.password && !payload.otp) {
|
|
221
|
+
throw `(password || otp) is required`;
|
|
222
|
+
}
|
|
223
|
+
// Define password policy
|
|
224
|
+
let passwordPolicy = (await Settings.get("PASSWORD_POLICY"));
|
|
225
|
+
if (!passwordPolicy)
|
|
226
|
+
passwordPolicy = "from_otp";
|
|
227
|
+
if ((await Settings.get("FIRSTNAME_REQUIRED")) &&
|
|
228
|
+
!payload.firstName) {
|
|
229
|
+
throw `firstName is required`;
|
|
230
|
+
}
|
|
231
|
+
if (passwordPolicy === "required" && !payload.password) {
|
|
232
|
+
throw `password is required`;
|
|
233
|
+
}
|
|
234
|
+
else if (passwordPolicy === "disabled" &&
|
|
235
|
+
payload.password) {
|
|
236
|
+
throw `Found password but passwordPolicy is: disabled`;
|
|
237
|
+
}
|
|
238
|
+
if ((await Settings.get("LOGIN_FIELD")) === undefined ||
|
|
239
|
+
(await Settings.get("LOGIN_FIELD")) === "phone") {
|
|
240
|
+
if (!payload.phone) {
|
|
241
|
+
throw `Phone is required, when login field is phone`;
|
|
242
|
+
}
|
|
243
|
+
else {
|
|
244
|
+
let genLogin = (payload.phone.code +
|
|
245
|
+
payload.phone.number +
|
|
246
|
+
payload.phone.additionalNumber).replace(/\D/g, "");
|
|
247
|
+
if (genLogin !== payload.login) {
|
|
248
|
+
throw `Login is: js (payload.phone.code+payload.phone.number+payload.phone.additionalNumber).replace(/\D/g, '')`;
|
|
249
|
+
}
|
|
250
|
+
}
|
|
251
|
+
}
|
|
252
|
+
if (payload.otp &&
|
|
253
|
+
!(await OneTimePassword.check(payload.login, payload.otp))) {
|
|
254
|
+
throw "OTP check failed";
|
|
255
|
+
}
|
|
256
|
+
let newUser = await User.create({
|
|
257
|
+
phone: payload.phone,
|
|
258
|
+
login: payload.login,
|
|
259
|
+
firstName: payload.firstName,
|
|
260
|
+
}).fetch();
|
|
261
|
+
if (passwordPolicy === "required") {
|
|
262
|
+
newUser = await User.setPassword(newUser.id, payload.password, null, true);
|
|
263
|
+
}
|
|
264
|
+
else if (passwordPolicy === "from_otp") {
|
|
265
|
+
newUser = await User.setPassword(newUser.id, payload.otp, null, true);
|
|
266
|
+
}
|
|
267
|
+
let message = {
|
|
268
|
+
deviceId: context.connectionParams.deviceId,
|
|
269
|
+
title: context.i18n.__("Success"),
|
|
270
|
+
type: "info",
|
|
271
|
+
message: context.i18n.__("New user created"),
|
|
272
|
+
};
|
|
273
|
+
// let action: Action = {
|
|
274
|
+
// type: "GoTo",
|
|
275
|
+
// data: {
|
|
276
|
+
// "section": "login",
|
|
277
|
+
// "delaySeconds": 5
|
|
278
|
+
// }
|
|
279
|
+
// }
|
|
280
|
+
return {
|
|
281
|
+
user: newUser,
|
|
282
|
+
message: message,
|
|
283
|
+
action: null,
|
|
284
|
+
};
|
|
285
|
+
}
|
|
286
|
+
catch (error) {
|
|
287
|
+
sails.log.error(error);
|
|
288
|
+
throw new Error(error);
|
|
289
|
+
}
|
|
290
|
+
},
|
|
291
|
+
},
|
|
292
|
+
// Authentication required
|
|
293
|
+
logout: {
|
|
294
|
+
def: `#graphql
|
|
295
|
+
logout(
|
|
296
|
+
"Optional field if not pass logout from current device",
|
|
297
|
+
deviceId: String
|
|
298
|
+
): Response`,
|
|
299
|
+
fn: async (parent, payload, context) => {
|
|
300
|
+
const auth = await jwt_1.JWTAuth.verify(context.connectionParams.authorization);
|
|
301
|
+
let deviceId;
|
|
302
|
+
if (!payload.deviceId) {
|
|
303
|
+
deviceId = auth.deviceId;
|
|
304
|
+
}
|
|
305
|
+
else {
|
|
306
|
+
let ud = await UserDevice.findOne({ name: payload.deviceId });
|
|
307
|
+
deviceId = ud.id;
|
|
308
|
+
}
|
|
309
|
+
if (!(await UserDevice.checkSession(auth.sessionId, auth.userId, {
|
|
310
|
+
lastIP: "IP",
|
|
311
|
+
userAgent: context.connectionParams["user-agent"],
|
|
312
|
+
}))) {
|
|
313
|
+
throw `Authentication failed`;
|
|
314
|
+
}
|
|
315
|
+
await UserDevice.update({ id: deviceId }, { isLogined: false });
|
|
316
|
+
let message = {
|
|
317
|
+
deviceId: deviceId,
|
|
318
|
+
title: context.i18n.__("Success"),
|
|
319
|
+
type: "info",
|
|
320
|
+
message: context.i18n.__("Logout"),
|
|
321
|
+
};
|
|
322
|
+
let action = undefined;
|
|
323
|
+
// Here should be Emmiter for midificate Action And Message
|
|
324
|
+
return {
|
|
325
|
+
message: message,
|
|
326
|
+
action: action,
|
|
327
|
+
};
|
|
328
|
+
},
|
|
329
|
+
},
|
|
330
|
+
logoutFromAllDevices: {
|
|
331
|
+
def: `logoutFromAllDevices: Response`,
|
|
332
|
+
fn: async (parent, payload, context) => {
|
|
333
|
+
const auth = await jwt_1.JWTAuth.verify(context.connectionParams.authorization);
|
|
334
|
+
if (!(await UserDevice.checkSession(auth.sessionId, auth.userId, {
|
|
335
|
+
lastIP: "IP",
|
|
336
|
+
userAgent: context.connectionParams["user-agent"],
|
|
337
|
+
}))) {
|
|
338
|
+
throw `Authentication failed`;
|
|
339
|
+
}
|
|
340
|
+
UserDevice.update({ user: auth.userId }, { isLogined: false });
|
|
341
|
+
let message = {
|
|
342
|
+
deviceId: null,
|
|
343
|
+
title: context.i18n.__("Success"),
|
|
344
|
+
type: "info",
|
|
345
|
+
message: context.i18n.__("Logout from all devices"),
|
|
346
|
+
};
|
|
347
|
+
let action = undefined;
|
|
348
|
+
// Here should be Emmiter for midificate Action And Message
|
|
349
|
+
return {
|
|
350
|
+
message: message,
|
|
351
|
+
action: action,
|
|
352
|
+
};
|
|
353
|
+
},
|
|
354
|
+
},
|
|
355
|
+
// Authentication required
|
|
356
|
+
favoriteDish: {
|
|
357
|
+
def: `#graphql
|
|
358
|
+
favoriteDish(
|
|
359
|
+
dishId: String!
|
|
360
|
+
): Boolean`,
|
|
361
|
+
fn: async (parent, payload, context) => {
|
|
362
|
+
const auth = await jwt_1.JWTAuth.verify(context.connectionParams.authorization);
|
|
363
|
+
await User.handleFavoriteDish(auth.userId, payload.dishId);
|
|
364
|
+
return true;
|
|
365
|
+
},
|
|
366
|
+
},
|
|
367
|
+
// Authentication required
|
|
368
|
+
userUpdate: {
|
|
369
|
+
def: `#graphql
|
|
370
|
+
userUpdate(
|
|
371
|
+
user: InputUser!
|
|
372
|
+
): UserResponse`,
|
|
373
|
+
fn: async (parent, payload, context) => {
|
|
374
|
+
const auth = await jwt_1.JWTAuth.verify(context.connectionParams.authorization);
|
|
375
|
+
let user = await User.updateOne({ id: auth.userId }, payload.user);
|
|
376
|
+
let message = {
|
|
377
|
+
deviceId: null,
|
|
378
|
+
title: context.i18n.__("Success"),
|
|
379
|
+
type: "info",
|
|
380
|
+
message: context.i18n.__("User was updated"),
|
|
381
|
+
};
|
|
382
|
+
// Here should be Emmiter for midificate Action And Message
|
|
383
|
+
return {
|
|
384
|
+
user: user,
|
|
385
|
+
message: message,
|
|
386
|
+
action: null,
|
|
387
|
+
};
|
|
388
|
+
},
|
|
389
|
+
},
|
|
390
|
+
userDelete: {
|
|
391
|
+
def: `#graphql
|
|
392
|
+
"""User delete method """
|
|
393
|
+
userDelete(
|
|
394
|
+
|
|
395
|
+
"(from otpRequest userDelete:%login%)"
|
|
396
|
+
otp: String!,
|
|
397
|
+
): Response`,
|
|
398
|
+
fn: async (parent, payload, context, info) => {
|
|
399
|
+
const auth = await jwt_1.JWTAuth.verify(context.connectionParams.authorization);
|
|
400
|
+
await User.delete(auth.userId, payload.otp);
|
|
401
|
+
let message = {
|
|
402
|
+
deviceId: null,
|
|
403
|
+
title: context.i18n.__("Success"),
|
|
404
|
+
type: "info",
|
|
405
|
+
message: context.i18n.__("The user will be deleted"),
|
|
406
|
+
};
|
|
407
|
+
let action = null;
|
|
408
|
+
// Here should be Emmiter for midificate Action And Message
|
|
409
|
+
return {
|
|
410
|
+
message: message,
|
|
411
|
+
action: action,
|
|
412
|
+
};
|
|
413
|
+
},
|
|
414
|
+
},
|
|
415
|
+
},
|
|
416
|
+
};
|