@skroz/profile-api 1.0.5 → 1.0.7
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/dist/resolvers/AuthResolver.d.ts +1 -1
- package/dist/resolvers/AuthResolver.js +22 -12
- package/dist/resolvers/ProfileResolver.d.ts +1 -1
- package/dist/resolvers/ProfileResolver.js +10 -3
- package/dist/types/index.d.ts +1 -1
- package/package.json +2 -2
- package/src/resolvers/AuthResolver.ts +23 -13
- package/src/resolvers/ProfileResolver.ts +11 -4
- package/src/types/index.ts +1 -1
|
@@ -2,7 +2,7 @@ import { ProfileAuthService } from '../services/ProfileAuthService';
|
|
|
2
2
|
import { ProfileContext } from '../types';
|
|
3
3
|
import { RegisterInput, LoginInput, ConfirmEmailInput, ForgotPasswordInput, RecoverPasswordInput } from '../dto';
|
|
4
4
|
export interface AuthResolverDependencies<TContext extends ProfileContext = ProfileContext> {
|
|
5
|
-
authService: ProfileAuthService;
|
|
5
|
+
authService: ProfileAuthService | (() => ProfileAuthService);
|
|
6
6
|
userType: any;
|
|
7
7
|
onUserCreated?: (user: any, ctx: TContext) => Promise<void>;
|
|
8
8
|
onLogin?: (user: any, ctx: TContext) => Promise<void>;
|
|
@@ -30,15 +30,21 @@ const ProfileAuthService_1 = require("../services/ProfileAuthService");
|
|
|
30
30
|
const dto_1 = require("../dto");
|
|
31
31
|
function createAuthResolver(deps) {
|
|
32
32
|
const { authService, onUserCreated, onLogin, onLogout, onEmailConfirmed, onPasswordRecovered, logTelegramBot, userType } = deps;
|
|
33
|
+
const getAuthService = () => {
|
|
34
|
+
if (typeof authService === 'function')
|
|
35
|
+
return authService();
|
|
36
|
+
return authService;
|
|
37
|
+
};
|
|
33
38
|
let AuthResolver = class AuthResolver {
|
|
34
39
|
register(input, ctx) {
|
|
35
40
|
return __awaiter(this, void 0, void 0, function* () {
|
|
36
41
|
const { t } = ctx;
|
|
37
|
-
|
|
42
|
+
const service = getAuthService();
|
|
43
|
+
if (yield service.db.isEmailTaken(input.email)) {
|
|
38
44
|
throw new Error(t('validation:auth.emailExists'));
|
|
39
45
|
}
|
|
40
|
-
const passwordHash = yield
|
|
41
|
-
const user = yield
|
|
46
|
+
const passwordHash = yield service.hashPassword(input.password);
|
|
47
|
+
const user = yield service.db.createUser({
|
|
42
48
|
email: input.email,
|
|
43
49
|
passwordHash,
|
|
44
50
|
});
|
|
@@ -59,12 +65,13 @@ function createAuthResolver(deps) {
|
|
|
59
65
|
login(input, ctx) {
|
|
60
66
|
return __awaiter(this, void 0, void 0, function* () {
|
|
61
67
|
const { t } = ctx;
|
|
62
|
-
const
|
|
68
|
+
const service = getAuthService();
|
|
69
|
+
const user = yield service.db.findUserByEmail(input.email);
|
|
63
70
|
if (!user)
|
|
64
71
|
throw new Error(t('validation:user.notFound'));
|
|
65
72
|
if (user.isBanned)
|
|
66
73
|
throw new Error(t('validation:user.banned'));
|
|
67
|
-
const isPasswordOk = yield
|
|
74
|
+
const isPasswordOk = yield service.verifyPassword(user.password, input.password);
|
|
68
75
|
if (!isPasswordOk)
|
|
69
76
|
throw new Error(t('validation:login.wrongPassword'));
|
|
70
77
|
const userAgent = decodeURI(ctx.req.get('user-agent') || '');
|
|
@@ -95,12 +102,13 @@ function createAuthResolver(deps) {
|
|
|
95
102
|
}
|
|
96
103
|
confirmEmail(input, ctx) {
|
|
97
104
|
return __awaiter(this, void 0, void 0, function* () {
|
|
98
|
-
const
|
|
105
|
+
const service = getAuthService();
|
|
106
|
+
const user = yield service.getUserByToken(ProfileAuthService_1.CONFIRMATION_REDIS_PREFIX, input.token);
|
|
99
107
|
if (!user)
|
|
100
108
|
throw new Error(ctx.t('validation:error.wrongCode'));
|
|
101
109
|
user.isEmailConfirmed = true;
|
|
102
110
|
yield user.save();
|
|
103
|
-
yield
|
|
111
|
+
yield service.removeTokenFromRedis(ProfileAuthService_1.CONFIRMATION_REDIS_PREFIX, user, input.token);
|
|
104
112
|
const userAgent = decodeURI(ctx.req.get('user-agent') || '');
|
|
105
113
|
yield ctx.req.session.create({
|
|
106
114
|
userId: user.id,
|
|
@@ -118,10 +126,11 @@ function createAuthResolver(deps) {
|
|
|
118
126
|
forgotPassword(input, ctx) {
|
|
119
127
|
return __awaiter(this, void 0, void 0, function* () {
|
|
120
128
|
const { t } = ctx;
|
|
121
|
-
const
|
|
129
|
+
const service = getAuthService();
|
|
130
|
+
const user = yield service.db.findUserByEmail(input.email);
|
|
122
131
|
if (!user)
|
|
123
132
|
throw new Error(t('validation:forgot.errors.notRegistered'));
|
|
124
|
-
const res = yield
|
|
133
|
+
const res = yield service.sendLink(user, 'recovery');
|
|
125
134
|
if (logTelegramBot) {
|
|
126
135
|
yield logTelegramBot.sendError(`${user.email || user.urlSlug} запросил(а) восстановление пароля`);
|
|
127
136
|
}
|
|
@@ -133,13 +142,14 @@ function createAuthResolver(deps) {
|
|
|
133
142
|
}
|
|
134
143
|
recoverPassword(input, ctx) {
|
|
135
144
|
return __awaiter(this, void 0, void 0, function* () {
|
|
136
|
-
const
|
|
145
|
+
const service = getAuthService();
|
|
146
|
+
const user = yield service.getUserByToken(ProfileAuthService_1.RECOVERY_REDIS_PREFIX, input.token);
|
|
137
147
|
if (!user)
|
|
138
148
|
throw new Error(ctx.t('validation:error.wrongCode'));
|
|
139
|
-
user.password = yield
|
|
149
|
+
user.password = yield service.hashPassword(input.password);
|
|
140
150
|
user.isTempPassword = false;
|
|
141
151
|
yield user.save();
|
|
142
|
-
yield
|
|
152
|
+
yield service.removeTokenFromRedis(ProfileAuthService_1.RECOVERY_REDIS_PREFIX, user, input.token);
|
|
143
153
|
const userAgent = decodeURI(ctx.req.get('user-agent') || '');
|
|
144
154
|
yield ctx.req.session.create({
|
|
145
155
|
userId: user.id,
|
|
@@ -2,7 +2,7 @@ import { ProfileAuthService } from '../services/ProfileAuthService';
|
|
|
2
2
|
import { ProfileContext } from '../types';
|
|
3
3
|
import { UpdateEmailInput, UpdatePasswordInput, UpdateProfileInput } from '../dto';
|
|
4
4
|
export interface ProfileResolverDependencies {
|
|
5
|
-
authService: ProfileAuthService;
|
|
5
|
+
authService: ProfileAuthService | (() => ProfileAuthService);
|
|
6
6
|
userType: any;
|
|
7
7
|
}
|
|
8
8
|
export declare function createProfileResolver<TContext extends ProfileContext = ProfileContext>(deps: ProfileResolverDependencies): {
|
|
@@ -29,13 +29,19 @@ const graphql_validators_1 = require("@os-team/graphql-validators");
|
|
|
29
29
|
const dto_1 = require("../dto");
|
|
30
30
|
function createProfileResolver(deps) {
|
|
31
31
|
const { authService, userType } = deps;
|
|
32
|
+
const getAuthService = () => {
|
|
33
|
+
if (typeof authService === 'function')
|
|
34
|
+
return authService();
|
|
35
|
+
return authService;
|
|
36
|
+
};
|
|
32
37
|
let ProfileResolver = class ProfileResolver {
|
|
33
38
|
updateEmail(input, ctx) {
|
|
34
39
|
return __awaiter(this, void 0, void 0, function* () {
|
|
35
40
|
const { user, t } = ctx;
|
|
36
41
|
if (!user)
|
|
37
42
|
throw new type_graphql_1.UnauthorizedError();
|
|
38
|
-
|
|
43
|
+
const service = getAuthService();
|
|
44
|
+
if (yield service.db.isEmailTaken(input.email, user.id)) {
|
|
39
45
|
throw new Error(t('validation:updateEmail.emailExists'));
|
|
40
46
|
}
|
|
41
47
|
user.email = input.email;
|
|
@@ -49,10 +55,11 @@ function createProfileResolver(deps) {
|
|
|
49
55
|
const { user, t } = ctx;
|
|
50
56
|
if (!user)
|
|
51
57
|
throw new type_graphql_1.UnauthorizedError();
|
|
52
|
-
const
|
|
58
|
+
const service = getAuthService();
|
|
59
|
+
const isOldPasswordOk = yield service.verifyPassword(user.password, input.oldPassword);
|
|
53
60
|
if (!isOldPasswordOk)
|
|
54
61
|
throw new Error(t('validation:updatePassword.wrongPassword'));
|
|
55
|
-
user.password = yield
|
|
62
|
+
user.password = yield service.hashPassword(input.password);
|
|
56
63
|
user.isTempPassword = false;
|
|
57
64
|
yield user.save();
|
|
58
65
|
return { ok: true };
|
package/dist/types/index.d.ts
CHANGED
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@skroz/profile-api",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.7",
|
|
4
4
|
"license": "MIT",
|
|
5
5
|
"repository": "git@gitlab.com:skroz/libs/utils.git",
|
|
6
6
|
"main": "dist/index.js",
|
|
@@ -41,5 +41,5 @@
|
|
|
41
41
|
"peerDependencies": {
|
|
42
42
|
"reflect-metadata": "0.1.13"
|
|
43
43
|
},
|
|
44
|
-
"gitHead": "
|
|
44
|
+
"gitHead": "8ad023661e836ee2ce5136d81d5dd778355c9583"
|
|
45
45
|
}
|
|
@@ -21,7 +21,7 @@ import {
|
|
|
21
21
|
} from '../dto';
|
|
22
22
|
|
|
23
23
|
export interface AuthResolverDependencies<TContext extends ProfileContext = ProfileContext> {
|
|
24
|
-
authService: ProfileAuthService;
|
|
24
|
+
authService: ProfileAuthService | (() => ProfileAuthService);
|
|
25
25
|
userType: any;
|
|
26
26
|
onUserCreated?: (user: any, ctx: TContext) => Promise<void>;
|
|
27
27
|
onLogin?: (user: any, ctx: TContext) => Promise<void>;
|
|
@@ -43,6 +43,11 @@ export function createAuthResolver<TContext extends ProfileContext = ProfileCont
|
|
|
43
43
|
userType
|
|
44
44
|
} = deps;
|
|
45
45
|
|
|
46
|
+
const getAuthService = (): ProfileAuthService => {
|
|
47
|
+
if (typeof authService === 'function') return authService();
|
|
48
|
+
return authService;
|
|
49
|
+
};
|
|
50
|
+
|
|
46
51
|
@Resolver(() => userType)
|
|
47
52
|
class AuthResolver {
|
|
48
53
|
@TransformArgs(registerTransformers, { arg: 'input' })
|
|
@@ -50,12 +55,13 @@ export function createAuthResolver<TContext extends ProfileContext = ProfileCont
|
|
|
50
55
|
@Mutation(() => StatusPayload)
|
|
51
56
|
async register(@Arg('input') input: RegisterInput, @Ctx() ctx: TContext) {
|
|
52
57
|
const { t } = ctx;
|
|
53
|
-
|
|
58
|
+
const service = getAuthService();
|
|
59
|
+
if (await service.db.isEmailTaken(input.email)) {
|
|
54
60
|
throw new Error(t('validation:auth.emailExists'));
|
|
55
61
|
}
|
|
56
62
|
|
|
57
|
-
const passwordHash = await
|
|
58
|
-
const user = await
|
|
63
|
+
const passwordHash = await service.hashPassword(input.password);
|
|
64
|
+
const user = await service.db.createUser({
|
|
59
65
|
email: input.email,
|
|
60
66
|
passwordHash,
|
|
61
67
|
});
|
|
@@ -79,12 +85,13 @@ export function createAuthResolver<TContext extends ProfileContext = ProfileCont
|
|
|
79
85
|
@Mutation(() => StatusPayload)
|
|
80
86
|
async login(@Arg('input') input: LoginInput, @Ctx() ctx: TContext) {
|
|
81
87
|
const { t } = ctx;
|
|
82
|
-
const
|
|
88
|
+
const service = getAuthService();
|
|
89
|
+
const user = await service.db.findUserByEmail(input.email);
|
|
83
90
|
if (!user) throw new Error(t('validation:user.notFound'));
|
|
84
91
|
|
|
85
92
|
if (user.isBanned) throw new Error(t('validation:user.banned'));
|
|
86
93
|
|
|
87
|
-
const isPasswordOk = await
|
|
94
|
+
const isPasswordOk = await service.verifyPassword(user.password!, input.password);
|
|
88
95
|
if (!isPasswordOk) throw new Error(t('validation:login.wrongPassword'));
|
|
89
96
|
|
|
90
97
|
const userAgent = decodeURI(ctx.req.get('user-agent') || '');
|
|
@@ -121,12 +128,13 @@ export function createAuthResolver<TContext extends ProfileContext = ProfileCont
|
|
|
121
128
|
@ValidateArgs(confirmEmailValidators, { arg: 'input', tKey: 'confirmEmail' })
|
|
122
129
|
@Mutation(() => StatusPayload)
|
|
123
130
|
async confirmEmail(@Arg('input') input: ConfirmEmailInput, @Ctx() ctx: TContext) {
|
|
124
|
-
const
|
|
131
|
+
const service = getAuthService();
|
|
132
|
+
const user = await service.getUserByToken(CONFIRMATION_REDIS_PREFIX, input.token);
|
|
125
133
|
if (!user) throw new Error(ctx.t('validation:error.wrongCode'));
|
|
126
134
|
|
|
127
135
|
user.isEmailConfirmed = true;
|
|
128
136
|
await user.save();
|
|
129
|
-
await
|
|
137
|
+
await service.removeTokenFromRedis(CONFIRMATION_REDIS_PREFIX, user, input.token);
|
|
130
138
|
|
|
131
139
|
const userAgent = decodeURI(ctx.req.get('user-agent') || '');
|
|
132
140
|
await ctx.req.session.create({
|
|
@@ -148,10 +156,11 @@ export function createAuthResolver<TContext extends ProfileContext = ProfileCont
|
|
|
148
156
|
@Mutation(() => SendTokenPayload)
|
|
149
157
|
async forgotPassword(@Arg('input') input: ForgotPasswordInput, @Ctx() ctx: TContext) {
|
|
150
158
|
const { t } = ctx;
|
|
151
|
-
const
|
|
159
|
+
const service = getAuthService();
|
|
160
|
+
const user = await service.db.findUserByEmail(input.email);
|
|
152
161
|
if (!user) throw new Error(t('validation:forgot.errors.notRegistered'));
|
|
153
162
|
|
|
154
|
-
const res = await
|
|
163
|
+
const res = await service.sendLink(user, 'recovery');
|
|
155
164
|
|
|
156
165
|
if (logTelegramBot) {
|
|
157
166
|
await logTelegramBot.sendError(`${user.email || user.urlSlug} запросил(а) восстановление пароля`);
|
|
@@ -167,13 +176,14 @@ export function createAuthResolver<TContext extends ProfileContext = ProfileCont
|
|
|
167
176
|
@ValidateArgs(recoverPasswordValidators, { arg: 'input', tKey: 'recover' })
|
|
168
177
|
@Mutation(() => StatusPayload)
|
|
169
178
|
async recoverPassword(@Arg('input') input: RecoverPasswordInput, @Ctx() ctx: TContext) {
|
|
170
|
-
const
|
|
179
|
+
const service = getAuthService();
|
|
180
|
+
const user = await service.getUserByToken(RECOVERY_REDIS_PREFIX, input.token);
|
|
171
181
|
if (!user) throw new Error(ctx.t('validation:error.wrongCode'));
|
|
172
182
|
|
|
173
|
-
user.password = await
|
|
183
|
+
user.password = await service.hashPassword(input.password);
|
|
174
184
|
user.isTempPassword = false;
|
|
175
185
|
await user.save();
|
|
176
|
-
await
|
|
186
|
+
await service.removeTokenFromRedis(RECOVERY_REDIS_PREFIX, user, input.token);
|
|
177
187
|
|
|
178
188
|
const userAgent = decodeURI(ctx.req.get('user-agent') || '');
|
|
179
189
|
await ctx.req.session.create({
|
|
@@ -18,13 +18,18 @@ import {
|
|
|
18
18
|
} from '../dto';
|
|
19
19
|
|
|
20
20
|
export interface ProfileResolverDependencies {
|
|
21
|
-
authService: ProfileAuthService;
|
|
21
|
+
authService: ProfileAuthService | (() => ProfileAuthService);
|
|
22
22
|
userType: any;
|
|
23
23
|
}
|
|
24
24
|
|
|
25
25
|
export function createProfileResolver<TContext extends ProfileContext = ProfileContext>(deps: ProfileResolverDependencies) {
|
|
26
26
|
const { authService, userType } = deps;
|
|
27
27
|
|
|
28
|
+
const getAuthService = (): ProfileAuthService => {
|
|
29
|
+
if (typeof authService === 'function') return authService();
|
|
30
|
+
return authService;
|
|
31
|
+
};
|
|
32
|
+
|
|
28
33
|
@Resolver(() => userType)
|
|
29
34
|
class ProfileResolver {
|
|
30
35
|
@Authorized()
|
|
@@ -35,7 +40,8 @@ export function createProfileResolver<TContext extends ProfileContext = ProfileC
|
|
|
35
40
|
const { user, t } = ctx;
|
|
36
41
|
if (!user) throw new UnauthorizedError();
|
|
37
42
|
|
|
38
|
-
|
|
43
|
+
const service = getAuthService();
|
|
44
|
+
if (await service.db.isEmailTaken(input.email, user.id)) {
|
|
39
45
|
throw new Error(t('validation:updateEmail.emailExists'));
|
|
40
46
|
}
|
|
41
47
|
|
|
@@ -54,10 +60,11 @@ export function createProfileResolver<TContext extends ProfileContext = ProfileC
|
|
|
54
60
|
const { user, t } = ctx;
|
|
55
61
|
if (!user) throw new UnauthorizedError();
|
|
56
62
|
|
|
57
|
-
const
|
|
63
|
+
const service = getAuthService();
|
|
64
|
+
const isOldPasswordOk = await service.verifyPassword(user.password!, input.oldPassword);
|
|
58
65
|
if (!isOldPasswordOk) throw new Error(t('validation:updatePassword.wrongPassword'));
|
|
59
66
|
|
|
60
|
-
user.password = await
|
|
67
|
+
user.password = await service.hashPassword(input.password);
|
|
61
68
|
user.isTempPassword = false;
|
|
62
69
|
await user.save();
|
|
63
70
|
|
package/src/types/index.ts
CHANGED