@skroz/profile-api 1.0.12 → 1.0.14

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.
@@ -1,16 +1,20 @@
1
1
  import PasswordInput from './PasswordInput';
2
- export default class RegisterInput extends PasswordInput {
2
+ export default class AuthInput extends PasswordInput {
3
3
  email: string;
4
4
  isUserAgreementAgree?: boolean;
5
5
  isPrivacyPolicyAgree?: boolean;
6
6
  }
7
+ export declare const loginValidators: {
8
+ email: import("@os-team/graphql-validators").Validator[];
9
+ password: import("@os-team/graphql-validators").Validator[];
10
+ };
7
11
  export declare const registerValidators: {
8
12
  password: import("@os-team/graphql-validators").Validator[];
9
13
  email: import("@os-team/graphql-validators").Validator[];
10
14
  isUserAgreementAgree: import("@os-team/graphql-validators").Validator[];
11
15
  isPrivacyPolicyAgree: import("@os-team/graphql-validators").Validator[];
12
16
  };
13
- export declare const registerTransformers: {
17
+ export declare const authTransformers: {
14
18
  password: import("@os-team/graphql-transformers").Transformer[];
15
19
  email: import("@os-team/graphql-transformers").Transformer[];
16
20
  };
@@ -45,29 +45,33 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
45
45
  return (mod && mod.__esModule) ? mod : { "default": mod };
46
46
  };
47
47
  Object.defineProperty(exports, "__esModule", { value: true });
48
- exports.registerTransformers = exports.registerValidators = void 0;
48
+ exports.authTransformers = exports.registerValidators = exports.loginValidators = void 0;
49
49
  const type_graphql_1 = require("type-graphql");
50
50
  const graphql_validators_1 = require("@os-team/graphql-validators");
51
51
  const graphql_transformers_1 = require("@os-team/graphql-transformers");
52
52
  const PasswordInput_1 = __importStar(require("./PasswordInput"));
53
53
  const isTrue_1 = __importDefault(require("../validators/isTrue"));
54
- let RegisterInput = class RegisterInput extends PasswordInput_1.default {
54
+ let AuthInput = class AuthInput extends PasswordInput_1.default {
55
55
  };
56
56
  __decorate([
57
57
  (0, type_graphql_1.Field)(),
58
58
  __metadata("design:type", String)
59
- ], RegisterInput.prototype, "email", void 0);
59
+ ], AuthInput.prototype, "email", void 0);
60
60
  __decorate([
61
61
  (0, type_graphql_1.Field)(() => Boolean, { nullable: true }),
62
62
  __metadata("design:type", Boolean)
63
- ], RegisterInput.prototype, "isUserAgreementAgree", void 0);
63
+ ], AuthInput.prototype, "isUserAgreementAgree", void 0);
64
64
  __decorate([
65
65
  (0, type_graphql_1.Field)(() => Boolean, { nullable: true }),
66
66
  __metadata("design:type", Boolean)
67
- ], RegisterInput.prototype, "isPrivacyPolicyAgree", void 0);
68
- RegisterInput = __decorate([
67
+ ], AuthInput.prototype, "isPrivacyPolicyAgree", void 0);
68
+ AuthInput = __decorate([
69
69
  (0, type_graphql_1.InputType)()
70
- ], RegisterInput);
71
- exports.default = RegisterInput;
70
+ ], AuthInput);
71
+ exports.default = AuthInput;
72
+ exports.loginValidators = {
73
+ email: [graphql_validators_1.isEmail],
74
+ password: [graphql_validators_1.isNotEmpty],
75
+ };
72
76
  exports.registerValidators = Object.assign({ email: [graphql_validators_1.isEmail], isUserAgreementAgree: [isTrue_1.default], isPrivacyPolicyAgree: [isTrue_1.default] }, PasswordInput_1.passwordValidators);
73
- exports.registerTransformers = Object.assign({ email: [graphql_transformers_1.trim, graphql_transformers_1.toLowerCase] }, PasswordInput_1.passwordTransformers);
77
+ exports.authTransformers = Object.assign({ email: [graphql_transformers_1.trim, graphql_transformers_1.toLowerCase] }, PasswordInput_1.passwordTransformers);
@@ -1,4 +1,4 @@
1
1
  export default class SendTokenPayload {
2
2
  codeIsSent: boolean;
3
- limitExpiresAt?: number;
3
+ limitExpiresAt: number;
4
4
  }
@@ -17,7 +17,7 @@ __decorate([
17
17
  __metadata("design:type", Boolean)
18
18
  ], SendTokenPayload.prototype, "codeIsSent", void 0);
19
19
  __decorate([
20
- (0, type_graphql_1.Field)(() => Number, { nullable: true }),
20
+ (0, type_graphql_1.Field)(() => Number),
21
21
  __metadata("design:type", Number)
22
22
  ], SendTokenPayload.prototype, "limitExpiresAt", void 0);
23
23
  SendTokenPayload = __decorate([
@@ -1,6 +1,5 @@
1
1
  export { default as PasswordInput, passwordTransformers, passwordValidators } from './PasswordInput';
2
- export { default as RegisterInput, registerTransformers, registerValidators } from './RegisterInput';
3
- export { default as LoginInput, loginTransformers, loginValidators } from './LoginInput';
2
+ export { default as AuthInput, registerValidators, loginValidators, authTransformers, } from './AuthInput';
4
3
  export { default as ForgotPasswordInput, forgotPasswordTransformers, forgotPasswordValidators } from './ForgotPasswordInput';
5
4
  export { default as ConfirmEmailInput, confirmEmailValidators } from './ConfirmEmailInput';
6
5
  export { default as StatusPayload } from './StatusPayload';
package/dist/dto/index.js CHANGED
@@ -3,19 +3,16 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
3
3
  return (mod && mod.__esModule) ? mod : { "default": mod };
4
4
  };
5
5
  Object.defineProperty(exports, "__esModule", { value: true });
6
- exports.recoverPasswordValidators = exports.recoverPasswordTransformers = exports.RecoverPasswordInput = exports.sendTokenValidators = exports.sendTokenTransformers = exports.SendTokenInput = exports.updateProfileValidators = exports.updateProfileTransformers = exports.UpdateProfileInput = exports.updateEmailValidators = exports.updateEmailTransformers = exports.UpdateEmailInput = exports.updatePasswordValidators = exports.updatePasswordTransformers = exports.UpdatePasswordInput = exports.SendTokenPayload = exports.StatusPayload = exports.confirmEmailValidators = exports.ConfirmEmailInput = exports.forgotPasswordValidators = exports.forgotPasswordTransformers = exports.ForgotPasswordInput = exports.loginValidators = exports.loginTransformers = exports.LoginInput = exports.registerValidators = exports.registerTransformers = exports.RegisterInput = exports.passwordValidators = exports.passwordTransformers = exports.PasswordInput = void 0;
6
+ exports.recoverPasswordValidators = exports.recoverPasswordTransformers = exports.RecoverPasswordInput = exports.sendTokenValidators = exports.sendTokenTransformers = exports.SendTokenInput = exports.updateProfileValidators = exports.updateProfileTransformers = exports.UpdateProfileInput = exports.updateEmailValidators = exports.updateEmailTransformers = exports.UpdateEmailInput = exports.updatePasswordValidators = exports.updatePasswordTransformers = exports.UpdatePasswordInput = exports.SendTokenPayload = exports.StatusPayload = exports.confirmEmailValidators = exports.ConfirmEmailInput = exports.forgotPasswordValidators = exports.forgotPasswordTransformers = exports.ForgotPasswordInput = exports.authTransformers = exports.loginValidators = exports.registerValidators = exports.AuthInput = exports.passwordValidators = exports.passwordTransformers = exports.PasswordInput = void 0;
7
7
  var PasswordInput_1 = require("./PasswordInput");
8
8
  Object.defineProperty(exports, "PasswordInput", { enumerable: true, get: function () { return __importDefault(PasswordInput_1).default; } });
9
9
  Object.defineProperty(exports, "passwordTransformers", { enumerable: true, get: function () { return PasswordInput_1.passwordTransformers; } });
10
10
  Object.defineProperty(exports, "passwordValidators", { enumerable: true, get: function () { return PasswordInput_1.passwordValidators; } });
11
- var RegisterInput_1 = require("./RegisterInput");
12
- Object.defineProperty(exports, "RegisterInput", { enumerable: true, get: function () { return __importDefault(RegisterInput_1).default; } });
13
- Object.defineProperty(exports, "registerTransformers", { enumerable: true, get: function () { return RegisterInput_1.registerTransformers; } });
14
- Object.defineProperty(exports, "registerValidators", { enumerable: true, get: function () { return RegisterInput_1.registerValidators; } });
15
- var LoginInput_1 = require("./LoginInput");
16
- Object.defineProperty(exports, "LoginInput", { enumerable: true, get: function () { return __importDefault(LoginInput_1).default; } });
17
- Object.defineProperty(exports, "loginTransformers", { enumerable: true, get: function () { return LoginInput_1.loginTransformers; } });
18
- Object.defineProperty(exports, "loginValidators", { enumerable: true, get: function () { return LoginInput_1.loginValidators; } });
11
+ var AuthInput_1 = require("./AuthInput");
12
+ Object.defineProperty(exports, "AuthInput", { enumerable: true, get: function () { return __importDefault(AuthInput_1).default; } });
13
+ Object.defineProperty(exports, "registerValidators", { enumerable: true, get: function () { return AuthInput_1.registerValidators; } });
14
+ Object.defineProperty(exports, "loginValidators", { enumerable: true, get: function () { return AuthInput_1.loginValidators; } });
15
+ Object.defineProperty(exports, "authTransformers", { enumerable: true, get: function () { return AuthInput_1.authTransformers; } });
19
16
  var ForgotPasswordInput_1 = require("./ForgotPasswordInput");
20
17
  Object.defineProperty(exports, "ForgotPasswordInput", { enumerable: true, get: function () { return __importDefault(ForgotPasswordInput_1).default; } });
21
18
  Object.defineProperty(exports, "forgotPasswordTransformers", { enumerable: true, get: function () { return ForgotPasswordInput_1.forgotPasswordTransformers; } });
@@ -103,12 +103,12 @@ function createAuthResolver(deps) {
103
103
  confirmEmail(input, ctx) {
104
104
  return __awaiter(this, void 0, void 0, function* () {
105
105
  const service = getAuthService();
106
- const user = yield service.getUserByToken(ProfileAuthService_1.CONFIRMATION_REDIS_PREFIX, input.token);
106
+ const user = yield service.getUserByToken(ProfileAuthService_1.AUTH_TOKEN_REDIS_PREFIX, input.token);
107
107
  if (!user)
108
108
  throw new Error(ctx.t('validation:error.wrongCode'));
109
109
  user.isEmailConfirmed = true;
110
110
  yield user.save();
111
- yield service.removeTokenFromRedis(ProfileAuthService_1.CONFIRMATION_REDIS_PREFIX, user, input.token);
111
+ yield service.removeTokenFromRedis(ProfileAuthService_1.AUTH_TOKEN_REDIS_PREFIX, user, input.token);
112
112
  const userAgent = decodeURI(ctx.req.get('user-agent') || '');
113
113
  yield ctx.req.session.create({
114
114
  userId: user.id,
@@ -123,35 +123,16 @@ function createAuthResolver(deps) {
123
123
  return user;
124
124
  });
125
125
  }
126
- forgotPassword(input, ctx) {
126
+ sendToken(input, ctx) {
127
127
  return __awaiter(this, void 0, void 0, function* () {
128
128
  const { t } = ctx;
129
129
  const service = getAuthService();
130
130
  const user = yield service.db.findUserByEmail(input.email);
131
131
  if (!user)
132
- throw new Error(t('validation:forgot.errors.notRegistered'));
133
- const res = yield service.sendLink(user, 'recovery');
134
- if (logTelegramBot) {
135
- yield logTelegramBot.sendError(`${user.email || user.urlSlug} запросил(а) восстановление пароля`);
136
- }
137
- return {
138
- codeIsSent: res.ok,
139
- limitExpiresAt: res.limitExpiresAt,
140
- };
141
- });
142
- }
143
- sendToken(input, ctx) {
144
- return __awaiter(this, void 0, void 0, function* () {
145
- const { user, t } = ctx;
146
- if (!user)
147
- throw new Error(t('validation:error.unauthorized'));
148
- const service = getAuthService();
149
- if (yield service.db.isEmailTaken(input.email, user.id)) {
150
- throw new Error(t('validation:auth.emailExists'));
151
- }
132
+ throw new Error(t('validation:user.notFound'));
152
133
  const res = yield service.sendLink(user, 'confirmation');
153
134
  if (logTelegramBot) {
154
- yield logTelegramBot.sendError(`Отправлен код подтверждения ${input.email}`);
135
+ yield logTelegramBot.sendError(`Отправлен код верификации ${input.email}`);
155
136
  }
156
137
  return {
157
138
  codeIsSent: res.ok,
@@ -162,13 +143,13 @@ function createAuthResolver(deps) {
162
143
  recoverPassword(input, ctx) {
163
144
  return __awaiter(this, void 0, void 0, function* () {
164
145
  const service = getAuthService();
165
- const user = yield service.getUserByToken(ProfileAuthService_1.RECOVERY_REDIS_PREFIX, input.token);
146
+ const user = yield service.getUserByToken(ProfileAuthService_1.AUTH_TOKEN_REDIS_PREFIX, input.token);
166
147
  if (!user)
167
148
  throw new Error(ctx.t('validation:error.wrongCode'));
168
149
  user.password = yield service.hashPassword(input.password);
169
150
  user.isTempPassword = false;
170
151
  yield user.save();
171
- yield service.removeTokenFromRedis(ProfileAuthService_1.RECOVERY_REDIS_PREFIX, user, input.token);
152
+ yield service.removeTokenFromRedis(ProfileAuthService_1.AUTH_TOKEN_REDIS_PREFIX, user, input.token);
172
153
  const userAgent = decodeURI(ctx.req.get('user-agent') || '');
173
154
  yield ctx.req.session.create({
174
155
  userId: user.id,
@@ -185,23 +166,23 @@ function createAuthResolver(deps) {
185
166
  }
186
167
  };
187
168
  __decorate([
188
- (0, graphql_transformers_1.TransformArgs)(dto_1.registerTransformers, { arg: 'input' }),
169
+ (0, graphql_transformers_1.TransformArgs)(dto_1.authTransformers, { arg: 'input' }),
189
170
  (0, graphql_validators_1.ValidateArgs)(dto_1.registerValidators, { arg: 'input', tKey: 'register' }),
190
171
  (0, type_graphql_1.Mutation)(() => userType),
191
172
  __param(0, (0, type_graphql_1.Arg)('input')),
192
173
  __param(1, (0, type_graphql_1.Ctx)()),
193
174
  __metadata("design:type", Function),
194
- __metadata("design:paramtypes", [dto_1.RegisterInput, Object]),
175
+ __metadata("design:paramtypes", [dto_1.AuthInput, Object]),
195
176
  __metadata("design:returntype", Promise)
196
177
  ], AuthResolver.prototype, "register", null);
197
178
  __decorate([
198
- (0, graphql_transformers_1.TransformArgs)(dto_1.loginTransformers, { arg: 'input' }),
179
+ (0, graphql_transformers_1.TransformArgs)(dto_1.authTransformers, { arg: 'input' }),
199
180
  (0, graphql_validators_1.ValidateArgs)(dto_1.loginValidators, { arg: 'input', tKey: 'register' }),
200
181
  (0, type_graphql_1.Mutation)(() => graphql_utils_1.StatusPayload),
201
182
  __param(0, (0, type_graphql_1.Arg)('input')),
202
183
  __param(1, (0, type_graphql_1.Ctx)()),
203
184
  __metadata("design:type", Function),
204
- __metadata("design:paramtypes", [dto_1.LoginInput, Object]),
185
+ __metadata("design:paramtypes", [dto_1.AuthInput, Object]),
205
186
  __metadata("design:returntype", Promise)
206
187
  ], AuthResolver.prototype, "login", null);
207
188
  __decorate([
@@ -224,16 +205,6 @@ function createAuthResolver(deps) {
224
205
  __metadata("design:paramtypes", [dto_1.ConfirmEmailInput, Object]),
225
206
  __metadata("design:returntype", Promise)
226
207
  ], AuthResolver.prototype, "confirmEmail", null);
227
- __decorate([
228
- (0, graphql_transformers_1.TransformArgs)(dto_1.forgotPasswordTransformers, { arg: 'input' }),
229
- (0, graphql_validators_1.ValidateArgs)(dto_1.forgotPasswordValidators, { arg: 'input', tKey: 'forgot' }),
230
- (0, type_graphql_1.Mutation)(() => dto_1.SendTokenPayload),
231
- __param(0, (0, type_graphql_1.Arg)('input')),
232
- __param(1, (0, type_graphql_1.Ctx)()),
233
- __metadata("design:type", Function),
234
- __metadata("design:paramtypes", [dto_1.ForgotPasswordInput, Object]),
235
- __metadata("design:returntype", Promise)
236
- ], AuthResolver.prototype, "forgotPassword", null);
237
208
  __decorate([
238
209
  (0, graphql_transformers_1.TransformArgs)(dto_1.sendTokenTransformers, { arg: 'input' }),
239
210
  (0, graphql_validators_1.ValidateArgs)(dto_1.sendTokenValidators, { arg: 'input', tKey: 'sendToken' }),
@@ -1,8 +1,7 @@
1
1
  import { Redis } from 'ioredis';
2
2
  import { AuthUser, ProfileAuthConfig, ProfileDbAdapter } from '../types';
3
3
  import { ProfileEmailService } from './ProfileEmailService';
4
- export declare const CONFIRMATION_REDIS_PREFIX = "conf";
5
- export declare const RECOVERY_REDIS_PREFIX = "rec";
4
+ export declare const AUTH_TOKEN_REDIS_PREFIX = "auth";
6
5
  export declare const TOKEN_REDIS_POSTFIX = "token";
7
6
  export declare const LAST_SENT_AT_REDIS_POSTFIX = "lastSentAt";
8
7
  export declare class ProfileAuthService {
@@ -12,10 +12,9 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
12
12
  return (mod && mod.__esModule) ? mod : { "default": mod };
13
13
  };
14
14
  Object.defineProperty(exports, "__esModule", { value: true });
15
- exports.ProfileAuthService = exports.LAST_SENT_AT_REDIS_POSTFIX = exports.TOKEN_REDIS_POSTFIX = exports.RECOVERY_REDIS_PREFIX = exports.CONFIRMATION_REDIS_PREFIX = void 0;
15
+ exports.ProfileAuthService = exports.LAST_SENT_AT_REDIS_POSTFIX = exports.TOKEN_REDIS_POSTFIX = exports.AUTH_TOKEN_REDIS_PREFIX = void 0;
16
16
  const argon2_1 = __importDefault(require("argon2"));
17
- exports.CONFIRMATION_REDIS_PREFIX = 'conf';
18
- exports.RECOVERY_REDIS_PREFIX = 'rec';
17
+ exports.AUTH_TOKEN_REDIS_PREFIX = 'auth';
19
18
  exports.TOKEN_REDIS_POSTFIX = 'token';
20
19
  exports.LAST_SENT_AT_REDIS_POSTFIX = 'lastSentAt';
21
20
  class ProfileAuthService {
@@ -51,9 +50,7 @@ class ProfileAuthService {
51
50
  }
52
51
  sendLink(user, type) {
53
52
  return __awaiter(this, void 0, void 0, function* () {
54
- const prefix = type === 'confirmation'
55
- ? exports.CONFIRMATION_REDIS_PREFIX
56
- : exports.RECOVERY_REDIS_PREFIX;
53
+ const prefix = exports.AUTH_TOKEN_REDIS_PREFIX;
57
54
  const ttlMinutes = type === 'confirmation'
58
55
  ? this.config.confirmationTokenLifetimeMinutes
59
56
  : this.config.recoveryTokenLifetimeMinutes;
@@ -80,7 +77,7 @@ class ProfileAuthService {
80
77
  if (!userIdStr)
81
78
  return null;
82
79
  const userId = Number(userIdStr);
83
- if (isNaN(userId))
80
+ if (Number.isNaN(userId))
84
81
  return null;
85
82
  return this.db.findUserById(userId);
86
83
  });
@@ -64,13 +64,8 @@ class ProfileEmailService {
64
64
  return __awaiter(this, void 0, void 0, function* () {
65
65
  if (!user.email)
66
66
  return false;
67
- const isConfirm = type === 'confirmation';
68
- const emailLocales = isConfirm
69
- ? this.locales.email.confirmEmail
70
- : this.locales.email.forgotPassword;
71
- const template = isConfirm
72
- ? types_1.ProfileEmailTemplate.CONFIRM_EMAIL
73
- : types_1.ProfileEmailTemplate.FORGOT_PASSWORD;
67
+ const emailLocales = this.locales.email.verificationCode;
68
+ const template = types_1.ProfileEmailTemplate.CONFIRM_EMAIL;
74
69
  return this.send(user.email, emailLocales.subject, template, {
75
70
  header: emailLocales.header,
76
71
  text: emailLocales.text,
@@ -82,6 +82,12 @@ export interface ProfileLocales {
82
82
  text: string;
83
83
  linkTitle: string;
84
84
  };
85
+ verificationCode: {
86
+ subject: string;
87
+ header: string;
88
+ text: string;
89
+ linkTitle: string;
90
+ };
85
91
  tempPassword: {
86
92
  subject: string;
87
93
  header: string;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@skroz/profile-api",
3
- "version": "1.0.12",
3
+ "version": "1.0.14",
4
4
  "license": "MIT",
5
5
  "repository": "git@gitlab.com:skroz/libs/utils.git",
6
6
  "main": "dist/index.js",
@@ -11,7 +11,7 @@
11
11
  "!**/*.test.ts"
12
12
  ],
13
13
  "scripts": {
14
- "clean": "rimraf dist",
14
+ "clean": "rm -rf dist",
15
15
  "build": "yarn clean && tsc --outDir dist && cp -R src/email-templates dist/email-templates",
16
16
  "ncu": "ncu -u"
17
17
  },
@@ -43,5 +43,5 @@
43
43
  "type-graphql": "^1.1.1",
44
44
  "typeorm": "^0.2.45"
45
45
  },
46
- "gitHead": "49e4b60af88db3e07b62591aed5d8086bd1f4c34"
46
+ "gitHead": "f2cd3aab624bb4b31ac099f978526c14689a34a9"
47
47
  }
@@ -1,21 +1,29 @@
1
1
  import { Field, InputType } from 'type-graphql';
2
- import { isEmail } from '@os-team/graphql-validators';
2
+ import { isEmail, isNotEmpty } from '@os-team/graphql-validators';
3
3
  import { toLowerCase, trim } from '@os-team/graphql-transformers';
4
- import PasswordInput, { passwordTransformers, passwordValidators } from './PasswordInput';
4
+ import PasswordInput, {
5
+ passwordTransformers,
6
+ passwordValidators,
7
+ } from './PasswordInput';
5
8
  import isTrue from '../validators/isTrue';
6
9
 
7
10
  @InputType()
8
- export default class RegisterInput extends PasswordInput {
11
+ export default class AuthInput extends PasswordInput {
9
12
  @Field()
10
- email!: string;
13
+ public email!: string;
11
14
 
12
15
  @Field(() => Boolean, { nullable: true })
13
- isUserAgreementAgree?: boolean;
16
+ public isUserAgreementAgree?: boolean;
14
17
 
15
18
  @Field(() => Boolean, { nullable: true })
16
- isPrivacyPolicyAgree?: boolean;
19
+ public isPrivacyPolicyAgree?: boolean;
17
20
  }
18
21
 
22
+ export const loginValidators = {
23
+ email: [isEmail],
24
+ password: [isNotEmpty],
25
+ };
26
+
19
27
  export const registerValidators = {
20
28
  email: [isEmail],
21
29
  isUserAgreementAgree: [isTrue],
@@ -23,7 +31,7 @@ export const registerValidators = {
23
31
  ...passwordValidators,
24
32
  };
25
33
 
26
- export const registerTransformers = {
34
+ export const authTransformers = {
27
35
  email: [trim, toLowerCase],
28
36
  ...passwordTransformers,
29
37
  };
@@ -5,6 +5,6 @@ export default class SendTokenPayload {
5
5
  @Field()
6
6
  public codeIsSent!: boolean;
7
7
 
8
- @Field(() => Number, { nullable: true })
9
- limitExpiresAt?: number;
8
+ @Field(() => Number)
9
+ public limitExpiresAt!: number;
10
10
  }
package/src/dto/index.ts CHANGED
@@ -1,6 +1,10 @@
1
1
  export { default as PasswordInput, passwordTransformers, passwordValidators } from './PasswordInput';
2
- export { default as RegisterInput, registerTransformers, registerValidators } from './RegisterInput';
3
- export { default as LoginInput, loginTransformers, loginValidators } from './LoginInput';
2
+ export {
3
+ default as AuthInput,
4
+ registerValidators,
5
+ loginValidators,
6
+ authTransformers,
7
+ } from './AuthInput';
4
8
  export { default as ForgotPasswordInput, forgotPasswordTransformers, forgotPasswordValidators } from './ForgotPasswordInput';
5
9
  export { default as ConfirmEmailInput, confirmEmailValidators } from './ConfirmEmailInput';
6
10
  export { default as StatusPayload } from './StatusPayload';
@@ -4,21 +4,15 @@ import { TransformArgs } from '@os-team/graphql-transformers';
4
4
  import { ValidateArgs } from '@os-team/graphql-validators';
5
5
  import {
6
6
  ProfileAuthService,
7
- CONFIRMATION_REDIS_PREFIX,
8
- RECOVERY_REDIS_PREFIX,
7
+ AUTH_TOKEN_REDIS_PREFIX,
9
8
  } from '../services/ProfileAuthService';
10
9
  import { ProfileContext } from '../types';
11
10
  import {
12
- RegisterInput,
13
- registerTransformers,
11
+ AuthInput,
14
12
  registerValidators,
15
- LoginInput,
16
- loginTransformers,
17
13
  loginValidators,
14
+ authTransformers,
18
15
  ConfirmEmailInput,
19
- ForgotPasswordInput,
20
- forgotPasswordTransformers,
21
- forgotPasswordValidators,
22
16
  RecoverPasswordInput,
23
17
  recoverPasswordTransformers,
24
18
  recoverPasswordValidators,
@@ -63,10 +57,10 @@ export function createAuthResolver<
63
57
 
64
58
  @Resolver(() => userType)
65
59
  class AuthResolver {
66
- @TransformArgs(registerTransformers, { arg: 'input' })
60
+ @TransformArgs(authTransformers, { arg: 'input' })
67
61
  @ValidateArgs(registerValidators, { arg: 'input', tKey: 'register' })
68
62
  @Mutation(() => userType)
69
- async register(@Arg('input') input: RegisterInput, @Ctx() ctx: TContext) {
63
+ async register(@Arg('input') input: AuthInput, @Ctx() ctx: TContext) {
70
64
  const { t } = ctx;
71
65
  const service = getAuthService();
72
66
  if (await service.db.isEmailTaken(input.email)) {
@@ -94,10 +88,10 @@ export function createAuthResolver<
94
88
  return user;
95
89
  }
96
90
 
97
- @TransformArgs(loginTransformers, { arg: 'input' })
91
+ @TransformArgs(authTransformers, { arg: 'input' })
98
92
  @ValidateArgs(loginValidators, { arg: 'input', tKey: 'register' })
99
93
  @Mutation(() => StatusPayload)
100
- async login(@Arg('input') input: LoginInput, @Ctx() ctx: TContext) {
94
+ async login(@Arg('input') input: AuthInput, @Ctx() ctx: TContext) {
101
95
  const { t } = ctx;
102
96
  const service = getAuthService();
103
97
  const user = await service.db.findUserByEmail(input.email);
@@ -153,7 +147,7 @@ export function createAuthResolver<
153
147
  ) {
154
148
  const service = getAuthService();
155
149
  const user = await service.getUserByToken(
156
- CONFIRMATION_REDIS_PREFIX,
150
+ AUTH_TOKEN_REDIS_PREFIX,
157
151
  input.token
158
152
  );
159
153
  if (!user) throw new Error(ctx.t('validation:error.wrongCode'));
@@ -161,7 +155,7 @@ export function createAuthResolver<
161
155
  user.isEmailConfirmed = true;
162
156
  await user.save();
163
157
  await service.removeTokenFromRedis(
164
- CONFIRMATION_REDIS_PREFIX,
158
+ AUTH_TOKEN_REDIS_PREFIX,
165
159
  user,
166
160
  input.token
167
161
  );
@@ -183,50 +177,20 @@ export function createAuthResolver<
183
177
  return user;
184
178
  }
185
179
 
186
- @TransformArgs(forgotPasswordTransformers, { arg: 'input' })
187
- @ValidateArgs(forgotPasswordValidators, { arg: 'input', tKey: 'forgot' })
188
- @Mutation(() => SendTokenPayload)
189
- async forgotPassword(
190
- @Arg('input') input: ForgotPasswordInput,
191
- @Ctx() ctx: TContext
192
- ) {
193
- const { t } = ctx;
194
- const service = getAuthService();
195
- const user = await service.db.findUserByEmail(input.email);
196
- if (!user) throw new Error(t('validation:forgot.errors.notRegistered'));
197
-
198
- const res = await service.sendLink(user, 'recovery');
199
-
200
- if (logTelegramBot) {
201
- await logTelegramBot.sendError(
202
- `${user.email || user.urlSlug} запросил(а) восстановление пароля`
203
- );
204
- }
205
-
206
- return {
207
- codeIsSent: res.ok,
208
- limitExpiresAt: res.limitExpiresAt,
209
- };
210
- }
211
-
212
180
  @TransformArgs(sendTokenTransformers, { arg: 'input' })
213
181
  @ValidateArgs(sendTokenValidators, { arg: 'input', tKey: 'sendToken' })
214
182
  @Mutation(() => SendTokenPayload)
215
183
  async sendToken(@Arg('input') input: SendTokenInput, @Ctx() ctx: TContext) {
216
- const { user, t } = ctx;
217
- if (!user) throw new Error(t('validation:error.unauthorized'));
218
-
184
+ const { t } = ctx;
219
185
  const service = getAuthService();
220
-
221
- if (await service.db.isEmailTaken(input.email, user.id)) {
222
- throw new Error(t('validation:auth.emailExists'));
223
- }
186
+ const user = await service.db.findUserByEmail(input.email);
187
+ if (!user) throw new Error(t('validation:user.notFound'));
224
188
 
225
189
  const res = await service.sendLink(user, 'confirmation');
226
190
 
227
191
  if (logTelegramBot) {
228
192
  await logTelegramBot.sendError(
229
- `Отправлен код подтверждения ${input.email}`
193
+ `Отправлен код верификации ${input.email}`
230
194
  );
231
195
  }
232
196
 
@@ -245,7 +209,7 @@ export function createAuthResolver<
245
209
  ) {
246
210
  const service = getAuthService();
247
211
  const user = await service.getUserByToken(
248
- RECOVERY_REDIS_PREFIX,
212
+ AUTH_TOKEN_REDIS_PREFIX,
249
213
  input.token
250
214
  );
251
215
  if (!user) throw new Error(ctx.t('validation:error.wrongCode'));
@@ -254,7 +218,7 @@ export function createAuthResolver<
254
218
  user.isTempPassword = false;
255
219
  await user.save();
256
220
  await service.removeTokenFromRedis(
257
- RECOVERY_REDIS_PREFIX,
221
+ AUTH_TOKEN_REDIS_PREFIX,
258
222
  user,
259
223
  input.token
260
224
  );
@@ -3,8 +3,7 @@ import { Redis } from 'ioredis';
3
3
  import { AuthUser, ProfileAuthConfig, ProfileDbAdapter } from '../types';
4
4
  import { ProfileEmailService } from './ProfileEmailService';
5
5
 
6
- export const CONFIRMATION_REDIS_PREFIX = 'conf';
7
- export const RECOVERY_REDIS_PREFIX = 'rec';
6
+ export const AUTH_TOKEN_REDIS_PREFIX = 'auth';
8
7
  export const TOKEN_REDIS_POSTFIX = 'token';
9
8
  export const LAST_SENT_AT_REDIS_POSTFIX = 'lastSentAt';
10
9
 
@@ -68,10 +67,7 @@ export class ProfileAuthService {
68
67
  }
69
68
 
70
69
  async sendLink(user: AuthUser, type: 'confirmation' | 'recovery') {
71
- const prefix =
72
- type === 'confirmation'
73
- ? CONFIRMATION_REDIS_PREFIX
74
- : RECOVERY_REDIS_PREFIX;
70
+ const prefix = AUTH_TOKEN_REDIS_PREFIX;
75
71
  const ttlMinutes =
76
72
  type === 'confirmation'
77
73
  ? this.config.confirmationTokenLifetimeMinutes
@@ -107,7 +103,7 @@ export class ProfileAuthService {
107
103
  if (!userIdStr) return null;
108
104
 
109
105
  const userId = Number(userIdStr);
110
- if (isNaN(userId)) return null;
106
+ if (Number.isNaN(userId)) return null;
111
107
 
112
108
  return this.db.findUserById(userId);
113
109
  }
@@ -87,14 +87,8 @@ export class ProfileEmailService {
87
87
  ) {
88
88
  if (!user.email) return false;
89
89
 
90
- const isConfirm = type === 'confirmation';
91
- const emailLocales = isConfirm
92
- ? this.locales.email.confirmEmail
93
- : this.locales.email.forgotPassword;
94
-
95
- const template = isConfirm
96
- ? ProfileEmailTemplate.CONFIRM_EMAIL
97
- : ProfileEmailTemplate.FORGOT_PASSWORD;
90
+ const emailLocales = this.locales.email.verificationCode;
91
+ const template = ProfileEmailTemplate.CONFIRM_EMAIL;
98
92
 
99
93
  return this.send(
100
94
  user.email,
@@ -84,6 +84,12 @@ export interface ProfileLocales {
84
84
  text: string;
85
85
  linkTitle: string;
86
86
  };
87
+ verificationCode: {
88
+ subject: string;
89
+ header: string;
90
+ text: string;
91
+ linkTitle: string;
92
+ };
87
93
  tempPassword: {
88
94
  subject: string;
89
95
  header: string;
@@ -1,12 +0,0 @@
1
- import PasswordInput from './PasswordInput';
2
- export default class LoginInput extends PasswordInput {
3
- email: string;
4
- }
5
- export declare const loginValidators: {
6
- email: import("@os-team/graphql-validators").Validator[];
7
- password: import("@os-team/graphql-validators").Validator[];
8
- };
9
- export declare const loginTransformers: {
10
- password: import("@os-team/graphql-transformers").Transformer[];
11
- email: import("@os-team/graphql-transformers").Transformer[];
12
- };
@@ -1,64 +0,0 @@
1
- "use strict";
2
- var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
- if (k2 === undefined) k2 = k;
4
- var desc = Object.getOwnPropertyDescriptor(m, k);
5
- if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
- desc = { enumerable: true, get: function() { return m[k]; } };
7
- }
8
- Object.defineProperty(o, k2, desc);
9
- }) : (function(o, m, k, k2) {
10
- if (k2 === undefined) k2 = k;
11
- o[k2] = m[k];
12
- }));
13
- var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
- Object.defineProperty(o, "default", { enumerable: true, value: v });
15
- }) : function(o, v) {
16
- o["default"] = v;
17
- });
18
- var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
19
- var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
20
- if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
21
- else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
22
- return c > 3 && r && Object.defineProperty(target, key, r), r;
23
- };
24
- var __importStar = (this && this.__importStar) || (function () {
25
- var ownKeys = function(o) {
26
- ownKeys = Object.getOwnPropertyNames || function (o) {
27
- var ar = [];
28
- for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
29
- return ar;
30
- };
31
- return ownKeys(o);
32
- };
33
- return function (mod) {
34
- if (mod && mod.__esModule) return mod;
35
- var result = {};
36
- if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
37
- __setModuleDefault(result, mod);
38
- return result;
39
- };
40
- })();
41
- var __metadata = (this && this.__metadata) || function (k, v) {
42
- if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
43
- };
44
- Object.defineProperty(exports, "__esModule", { value: true });
45
- exports.loginTransformers = exports.loginValidators = void 0;
46
- const type_graphql_1 = require("type-graphql");
47
- const graphql_validators_1 = require("@os-team/graphql-validators");
48
- const graphql_transformers_1 = require("@os-team/graphql-transformers");
49
- const PasswordInput_1 = __importStar(require("./PasswordInput"));
50
- let LoginInput = class LoginInput extends PasswordInput_1.default {
51
- };
52
- __decorate([
53
- (0, type_graphql_1.Field)(),
54
- __metadata("design:type", String)
55
- ], LoginInput.prototype, "email", void 0);
56
- LoginInput = __decorate([
57
- (0, type_graphql_1.InputType)()
58
- ], LoginInput);
59
- exports.default = LoginInput;
60
- exports.loginValidators = {
61
- email: [graphql_validators_1.isEmail],
62
- password: [graphql_validators_1.isNotEmpty],
63
- };
64
- exports.loginTransformers = Object.assign({ email: [graphql_transformers_1.trim, graphql_transformers_1.toLowerCase] }, PasswordInput_1.passwordTransformers);
@@ -1,20 +0,0 @@
1
- import { Field, InputType } from 'type-graphql';
2
- import { isEmail, isNotEmpty } from '@os-team/graphql-validators';
3
- import { toLowerCase, trim } from '@os-team/graphql-transformers';
4
- import PasswordInput, { passwordTransformers } from './PasswordInput';
5
-
6
- @InputType()
7
- export default class LoginInput extends PasswordInput {
8
- @Field()
9
- email!: string;
10
- }
11
-
12
- export const loginValidators = {
13
- email: [isEmail],
14
- password: [isNotEmpty],
15
- };
16
-
17
- export const loginTransformers = {
18
- email: [trim, toLowerCase],
19
- ...passwordTransformers,
20
- };