@skroz/profile-api 1.0.16 → 1.0.17

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.
Files changed (42) hide show
  1. package/dist/adapters/TypeOrmProfileAdapter.d.ts +4 -1
  2. package/dist/adapters/TypeOrmProfileAdapter.js +15 -1
  3. package/dist/dto/OauthInput.d.ts +14 -0
  4. package/dist/dto/OauthInput.js +65 -0
  5. package/dist/dto/index.d.ts +1 -0
  6. package/dist/dto/index.js +4 -1
  7. package/dist/entities/TypeOrmBaseUser.d.ts +5 -0
  8. package/dist/entities/TypeOrmBaseUser.js +20 -0
  9. package/dist/index.d.ts +2 -0
  10. package/dist/index.js +2 -0
  11. package/dist/oauth/AppleOauth.d.ts +13 -0
  12. package/dist/oauth/AppleOauth.js +84 -0
  13. package/dist/oauth/GoogleOauth.d.ts +12 -0
  14. package/dist/oauth/GoogleOauth.js +54 -0
  15. package/dist/oauth/MailOauth.d.ts +12 -0
  16. package/dist/oauth/MailOauth.js +53 -0
  17. package/dist/oauth/OAuthProvider.d.ts +9 -0
  18. package/dist/oauth/OAuthProvider.js +2 -0
  19. package/dist/oauth/VKOauth.d.ts +12 -0
  20. package/dist/oauth/VKOauth.js +47 -0
  21. package/dist/oauth/YandexOauth.d.ts +11 -0
  22. package/dist/oauth/YandexOauth.js +56 -0
  23. package/dist/oauth/index.d.ts +6 -0
  24. package/dist/oauth/index.js +22 -0
  25. package/dist/resolvers/createOauthResolver.d.ts +12 -0
  26. package/dist/resolvers/createOauthResolver.js +146 -0
  27. package/dist/types/index.d.ts +4 -1
  28. package/package.json +3 -2
  29. package/src/adapters/TypeOrmProfileAdapter.ts +13 -2
  30. package/src/dto/OauthInput.ts +37 -0
  31. package/src/dto/index.ts +1 -0
  32. package/src/entities/TypeOrmBaseUser.ts +15 -0
  33. package/src/index.ts +2 -0
  34. package/src/oauth/AppleOauth.ts +83 -0
  35. package/src/oauth/GoogleOauth.ts +47 -0
  36. package/src/oauth/MailOauth.ts +49 -0
  37. package/src/oauth/OAuthProvider.ts +10 -0
  38. package/src/oauth/VKOauth.ts +43 -0
  39. package/src/oauth/YandexOauth.ts +49 -0
  40. package/src/oauth/index.ts +6 -0
  41. package/src/resolvers/createOauthResolver.ts +136 -0
  42. package/src/types/index.ts +3 -1
@@ -7,8 +7,11 @@ export declare class TypeOrmProfileAdapter implements ProfileDbAdapter {
7
7
  findUserById(id: number): Promise<AuthUser | null>;
8
8
  findUserByTelegramId(telegramId: string): Promise<AuthUser | null>;
9
9
  createUser(data: {
10
- email: string;
10
+ email?: string | null;
11
11
  passwordHash: string;
12
+ isTempPassword?: boolean;
12
13
  }): Promise<AuthUser>;
13
14
  isEmailTaken(email: string, excludeUserId?: number): Promise<boolean>;
15
+ findUserByProviderId(provider: string, id: string): Promise<AuthUser | null>;
16
+ updateUserProviderId(userId: number, provider: string, id: string): Promise<void>;
14
17
  }
@@ -35,10 +35,12 @@ class TypeOrmProfileAdapter {
35
35
  }
36
36
  createUser(data) {
37
37
  return __awaiter(this, void 0, void 0, function* () {
38
+ var _a;
38
39
  const user = this.repo.create({
39
- email: data.email.toLowerCase(),
40
+ email: data.email ? data.email.toLowerCase() : null,
40
41
  password: data.passwordHash,
41
42
  isEmailConfirmed: false,
43
+ isTempPassword: (_a = data.isTempPassword) !== null && _a !== void 0 ? _a : false,
42
44
  });
43
45
  return (yield this.repo.save(user));
44
46
  });
@@ -53,5 +55,17 @@ class TypeOrmProfileAdapter {
53
55
  return count > 0;
54
56
  });
55
57
  }
58
+ findUserByProviderId(provider, id) {
59
+ return __awaiter(this, void 0, void 0, function* () {
60
+ const field = `${provider}Id`;
61
+ return this.repo.findOne({ where: { [field]: id } });
62
+ });
63
+ }
64
+ updateUserProviderId(userId, provider, id) {
65
+ return __awaiter(this, void 0, void 0, function* () {
66
+ const field = `${provider}Id`;
67
+ yield this.repo.update(userId, { [field]: id });
68
+ });
69
+ }
56
70
  }
57
71
  exports.TypeOrmProfileAdapter = TypeOrmProfileAdapter;
@@ -0,0 +1,14 @@
1
+ export declare class TelegramAuthData {
2
+ id: string;
3
+ first_name: string;
4
+ last_name?: string;
5
+ username?: string;
6
+ photo_url?: string;
7
+ auth_date: string;
8
+ hash: string;
9
+ }
10
+ export declare class OauthLoginInput {
11
+ provider: string;
12
+ code?: string;
13
+ tgData?: TelegramAuthData;
14
+ }
@@ -0,0 +1,65 @@
1
+ "use strict";
2
+ var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
3
+ var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
4
+ if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
5
+ 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;
6
+ return c > 3 && r && Object.defineProperty(target, key, r), r;
7
+ };
8
+ var __metadata = (this && this.__metadata) || function (k, v) {
9
+ if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
10
+ };
11
+ Object.defineProperty(exports, "__esModule", { value: true });
12
+ exports.OauthLoginInput = exports.TelegramAuthData = void 0;
13
+ const type_graphql_1 = require("type-graphql");
14
+ let TelegramAuthData = class TelegramAuthData {
15
+ };
16
+ exports.TelegramAuthData = TelegramAuthData;
17
+ __decorate([
18
+ (0, type_graphql_1.Field)(),
19
+ __metadata("design:type", String)
20
+ ], TelegramAuthData.prototype, "id", void 0);
21
+ __decorate([
22
+ (0, type_graphql_1.Field)(),
23
+ __metadata("design:type", String)
24
+ ], TelegramAuthData.prototype, "first_name", void 0);
25
+ __decorate([
26
+ (0, type_graphql_1.Field)({ nullable: true }),
27
+ __metadata("design:type", String)
28
+ ], TelegramAuthData.prototype, "last_name", void 0);
29
+ __decorate([
30
+ (0, type_graphql_1.Field)({ nullable: true }),
31
+ __metadata("design:type", String)
32
+ ], TelegramAuthData.prototype, "username", void 0);
33
+ __decorate([
34
+ (0, type_graphql_1.Field)({ nullable: true }),
35
+ __metadata("design:type", String)
36
+ ], TelegramAuthData.prototype, "photo_url", void 0);
37
+ __decorate([
38
+ (0, type_graphql_1.Field)(),
39
+ __metadata("design:type", String)
40
+ ], TelegramAuthData.prototype, "auth_date", void 0);
41
+ __decorate([
42
+ (0, type_graphql_1.Field)(),
43
+ __metadata("design:type", String)
44
+ ], TelegramAuthData.prototype, "hash", void 0);
45
+ exports.TelegramAuthData = TelegramAuthData = __decorate([
46
+ (0, type_graphql_1.InputType)()
47
+ ], TelegramAuthData);
48
+ let OauthLoginInput = class OauthLoginInput {
49
+ };
50
+ exports.OauthLoginInput = OauthLoginInput;
51
+ __decorate([
52
+ (0, type_graphql_1.Field)(),
53
+ __metadata("design:type", String)
54
+ ], OauthLoginInput.prototype, "provider", void 0);
55
+ __decorate([
56
+ (0, type_graphql_1.Field)({ nullable: true }),
57
+ __metadata("design:type", String)
58
+ ], OauthLoginInput.prototype, "code", void 0);
59
+ __decorate([
60
+ (0, type_graphql_1.Field)(() => TelegramAuthData, { nullable: true }),
61
+ __metadata("design:type", TelegramAuthData)
62
+ ], OauthLoginInput.prototype, "tgData", void 0);
63
+ exports.OauthLoginInput = OauthLoginInput = __decorate([
64
+ (0, type_graphql_1.InputType)()
65
+ ], OauthLoginInput);
@@ -9,3 +9,4 @@ export { default as UpdateEmailInput, updateEmailTransformers, updateEmailValida
9
9
  export { default as UpdateProfileInput, updateProfileTransformers, updateProfileValidators } from './UpdateProfileInput';
10
10
  export { default as SendTokenInput, sendTokenTransformers, sendTokenValidators } from './SendTokenInput';
11
11
  export { default as RecoverPasswordInput, recoverPasswordTransformers, recoverPasswordValidators } from './RecoverPasswordInput';
12
+ export { OauthLoginInput, TelegramAuthData } from './OauthInput';
package/dist/dto/index.js CHANGED
@@ -3,7 +3,7 @@ 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.authTransformers = exports.loginValidators = exports.registerValidators = exports.AuthInput = exports.passwordValidators = exports.passwordTransformers = exports.PasswordInput = void 0;
6
+ exports.TelegramAuthData = exports.OauthLoginInput = 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; } });
@@ -44,3 +44,6 @@ var RecoverPasswordInput_1 = require("./RecoverPasswordInput");
44
44
  Object.defineProperty(exports, "RecoverPasswordInput", { enumerable: true, get: function () { return __importDefault(RecoverPasswordInput_1).default; } });
45
45
  Object.defineProperty(exports, "recoverPasswordTransformers", { enumerable: true, get: function () { return RecoverPasswordInput_1.recoverPasswordTransformers; } });
46
46
  Object.defineProperty(exports, "recoverPasswordValidators", { enumerable: true, get: function () { return RecoverPasswordInput_1.recoverPasswordValidators; } });
47
+ var OauthInput_1 = require("./OauthInput");
48
+ Object.defineProperty(exports, "OauthLoginInput", { enumerable: true, get: function () { return OauthInput_1.OauthLoginInput; } });
49
+ Object.defineProperty(exports, "TelegramAuthData", { enumerable: true, get: function () { return OauthInput_1.TelegramAuthData; } });
@@ -17,6 +17,11 @@ export declare abstract class TypeOrmBaseUser extends TypeORMBaseEntity {
17
17
  isDeleted: boolean;
18
18
  urlSlug?: string;
19
19
  telegramId: string | null;
20
+ googleId?: string | null;
21
+ vkId?: string | null;
22
+ yaId?: string | null;
23
+ mailId?: string | null;
24
+ appleId?: string | null;
20
25
  avatar?: string | null;
21
26
  lastSeenAt: Date;
22
27
  checkOnline(seconds: number): boolean;
@@ -92,6 +92,26 @@ __decorate([
92
92
  (0, typeorm_1.Column)({ type: 'varchar', nullable: true, unique: true }),
93
93
  __metadata("design:type", Object)
94
94
  ], TypeOrmBaseUser.prototype, "telegramId", void 0);
95
+ __decorate([
96
+ (0, typeorm_1.Column)({ type: 'varchar', nullable: true }),
97
+ __metadata("design:type", Object)
98
+ ], TypeOrmBaseUser.prototype, "googleId", void 0);
99
+ __decorate([
100
+ (0, typeorm_1.Column)({ type: 'varchar', nullable: true }),
101
+ __metadata("design:type", Object)
102
+ ], TypeOrmBaseUser.prototype, "vkId", void 0);
103
+ __decorate([
104
+ (0, typeorm_1.Column)({ type: 'varchar', nullable: true }),
105
+ __metadata("design:type", Object)
106
+ ], TypeOrmBaseUser.prototype, "yaId", void 0);
107
+ __decorate([
108
+ (0, typeorm_1.Column)({ type: 'varchar', nullable: true }),
109
+ __metadata("design:type", Object)
110
+ ], TypeOrmBaseUser.prototype, "mailId", void 0);
111
+ __decorate([
112
+ (0, typeorm_1.Column)({ type: 'varchar', nullable: true }),
113
+ __metadata("design:type", Object)
114
+ ], TypeOrmBaseUser.prototype, "appleId", void 0);
95
115
  __decorate([
96
116
  (0, type_graphql_1.Field)(() => String, { nullable: true }),
97
117
  (0, typeorm_1.Column)({ type: 'varchar', nullable: true }),
package/dist/index.d.ts CHANGED
@@ -6,3 +6,5 @@ export * from './services/ProfileEmailService';
6
6
  export * from './dto';
7
7
  export * from './resolvers/AuthResolver';
8
8
  export * from './resolvers/ProfileResolver';
9
+ export * from './resolvers/createOauthResolver';
10
+ export * from './oauth';
package/dist/index.js CHANGED
@@ -22,3 +22,5 @@ __exportStar(require("./services/ProfileEmailService"), exports);
22
22
  __exportStar(require("./dto"), exports);
23
23
  __exportStar(require("./resolvers/AuthResolver"), exports);
24
24
  __exportStar(require("./resolvers/ProfileResolver"), exports);
25
+ __exportStar(require("./resolvers/createOauthResolver"), exports);
26
+ __exportStar(require("./oauth"), exports);
@@ -0,0 +1,13 @@
1
+ import { OAuthProfile, OAuthProvider } from './OAuthProvider';
2
+ interface AppleOauthConfig {
3
+ clientId: string;
4
+ teamId: string;
5
+ keyId: string;
6
+ privateKey: string;
7
+ }
8
+ export declare class AppleOauth implements OAuthProvider {
9
+ private config;
10
+ constructor(config: AppleOauthConfig);
11
+ exchangeCode(code: string): Promise<OAuthProfile>;
12
+ }
13
+ export {};
@@ -0,0 +1,84 @@
1
+ "use strict";
2
+ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
3
+ function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
4
+ return new (P || (P = Promise))(function (resolve, reject) {
5
+ function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
6
+ function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
7
+ function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
8
+ step((generator = generator.apply(thisArg, _arguments || [])).next());
9
+ });
10
+ };
11
+ var __importDefault = (this && this.__importDefault) || function (mod) {
12
+ return (mod && mod.__esModule) ? mod : { "default": mod };
13
+ };
14
+ Object.defineProperty(exports, "__esModule", { value: true });
15
+ exports.AppleOauth = void 0;
16
+ const isomorphic_unfetch_1 = __importDefault(require("isomorphic-unfetch"));
17
+ const crypto_1 = __importDefault(require("crypto"));
18
+ function base64urlEncode(str) {
19
+ const buf = typeof str === 'string' ? Buffer.from(str) : str;
20
+ return buf.toString('base64').replace(/\+/g, '-').replace(/\//g, '_').replace(/=/g, '');
21
+ }
22
+ function generateClientSecret(config) {
23
+ const now = Math.floor(Date.now() / 1000);
24
+ const header = base64urlEncode(JSON.stringify({ alg: 'ES256', kid: config.keyId }));
25
+ const payload = base64urlEncode(JSON.stringify({
26
+ iss: config.teamId,
27
+ iat: now,
28
+ exp: now + 15777000, // ~6 months
29
+ aud: 'https://appleid.apple.com',
30
+ sub: config.clientId,
31
+ }));
32
+ const signingInput = `${header}.${payload}`;
33
+ const sign = crypto_1.default.createSign('SHA256');
34
+ sign.update(signingInput);
35
+ const signature = sign.sign(config.privateKey);
36
+ // Convert DER to base64url
37
+ const signatureBase64url = base64urlEncode(signature);
38
+ return `${signingInput}.${signatureBase64url}`;
39
+ }
40
+ function decodeJwtPayload(token) {
41
+ const parts = token.split('.');
42
+ if (parts.length < 2)
43
+ throw new Error('Invalid JWT');
44
+ const payload = Buffer.from(parts[1], 'base64').toString('utf8');
45
+ return JSON.parse(payload);
46
+ }
47
+ class AppleOauth {
48
+ constructor(config) {
49
+ this.config = config;
50
+ }
51
+ exchangeCode(code) {
52
+ return __awaiter(this, void 0, void 0, function* () {
53
+ const clientSecret = generateClientSecret(this.config);
54
+ const tokenResponse = yield (0, isomorphic_unfetch_1.default)('https://appleid.apple.com/auth/token', {
55
+ method: 'POST',
56
+ headers: { 'Content-Type': 'application/x-www-form-urlencoded' },
57
+ body: new URLSearchParams({
58
+ grant_type: 'authorization_code',
59
+ client_id: this.config.clientId,
60
+ client_secret: clientSecret,
61
+ code,
62
+ }).toString(),
63
+ });
64
+ const tokenData = yield tokenResponse.json();
65
+ if (!tokenData.id_token) {
66
+ throw new Error(`Apple OAuth error: ${tokenData.error || 'no id_token'}`);
67
+ }
68
+ // Apple sends user data only on first authorization — decode from id_token
69
+ const idTokenPayload = decodeJwtPayload(tokenData.id_token);
70
+ const appleId = idTokenPayload.sub;
71
+ if (!appleId) {
72
+ throw new Error('Apple OAuth: failed to get user ID from id_token');
73
+ }
74
+ return {
75
+ providerId: appleId,
76
+ // Apple provides email only on first authorization
77
+ email: idTokenPayload.email || null,
78
+ name: null, // Apple does not provide name in id_token; handle via front-end form on first login
79
+ avatarUrl: null, // Apple does not provide avatar
80
+ };
81
+ });
82
+ }
83
+ }
84
+ exports.AppleOauth = AppleOauth;
@@ -0,0 +1,12 @@
1
+ import { OAuthProfile, OAuthProvider } from './OAuthProvider';
2
+ interface GoogleOauthConfig {
3
+ clientId: string;
4
+ clientSecret: string;
5
+ redirectUri: string;
6
+ }
7
+ export declare class GoogleOauth implements OAuthProvider {
8
+ private config;
9
+ constructor(config: GoogleOauthConfig);
10
+ exchangeCode(code: string): Promise<OAuthProfile>;
11
+ }
12
+ export {};
@@ -0,0 +1,54 @@
1
+ "use strict";
2
+ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
3
+ function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
4
+ return new (P || (P = Promise))(function (resolve, reject) {
5
+ function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
6
+ function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
7
+ function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
8
+ step((generator = generator.apply(thisArg, _arguments || [])).next());
9
+ });
10
+ };
11
+ var __importDefault = (this && this.__importDefault) || function (mod) {
12
+ return (mod && mod.__esModule) ? mod : { "default": mod };
13
+ };
14
+ Object.defineProperty(exports, "__esModule", { value: true });
15
+ exports.GoogleOauth = void 0;
16
+ const isomorphic_unfetch_1 = __importDefault(require("isomorphic-unfetch"));
17
+ class GoogleOauth {
18
+ constructor(config) {
19
+ this.config = config;
20
+ }
21
+ exchangeCode(code) {
22
+ return __awaiter(this, void 0, void 0, function* () {
23
+ const tokenResponse = yield (0, isomorphic_unfetch_1.default)('https://oauth2.googleapis.com/token', {
24
+ method: 'POST',
25
+ headers: { 'Content-Type': 'application/x-www-form-urlencoded' },
26
+ body: new URLSearchParams({
27
+ grant_type: 'authorization_code',
28
+ client_id: this.config.clientId,
29
+ client_secret: this.config.clientSecret,
30
+ redirect_uri: this.config.redirectUri,
31
+ code,
32
+ }).toString(),
33
+ });
34
+ const tokenData = yield tokenResponse.json();
35
+ if (!tokenData.access_token) {
36
+ throw new Error(`Google OAuth error: ${tokenData.error_description || tokenData.error}`);
37
+ }
38
+ const userResponse = yield (0, isomorphic_unfetch_1.default)('https://www.googleapis.com/oauth2/v3/userinfo', {
39
+ headers: { Authorization: `Bearer ${tokenData.access_token}` },
40
+ });
41
+ const user = yield userResponse.json();
42
+ if (!user.sub) {
43
+ throw new Error('Google OAuth: failed to get user profile');
44
+ }
45
+ return {
46
+ providerId: user.sub,
47
+ email: user.email || null,
48
+ name: user.name || null,
49
+ avatarUrl: user.picture || null,
50
+ };
51
+ });
52
+ }
53
+ }
54
+ exports.GoogleOauth = GoogleOauth;
@@ -0,0 +1,12 @@
1
+ import { OAuthProfile, OAuthProvider } from './OAuthProvider';
2
+ interface MailOauthConfig {
3
+ clientId: string;
4
+ clientSecret: string;
5
+ redirectUri: string;
6
+ }
7
+ export declare class MailOauth implements OAuthProvider {
8
+ private config;
9
+ constructor(config: MailOauthConfig);
10
+ exchangeCode(code: string): Promise<OAuthProfile>;
11
+ }
12
+ export {};
@@ -0,0 +1,53 @@
1
+ "use strict";
2
+ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
3
+ function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
4
+ return new (P || (P = Promise))(function (resolve, reject) {
5
+ function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
6
+ function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
7
+ function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
8
+ step((generator = generator.apply(thisArg, _arguments || [])).next());
9
+ });
10
+ };
11
+ var __importDefault = (this && this.__importDefault) || function (mod) {
12
+ return (mod && mod.__esModule) ? mod : { "default": mod };
13
+ };
14
+ Object.defineProperty(exports, "__esModule", { value: true });
15
+ exports.MailOauth = void 0;
16
+ const isomorphic_unfetch_1 = __importDefault(require("isomorphic-unfetch"));
17
+ const crypto_1 = __importDefault(require("crypto"));
18
+ class MailOauth {
19
+ constructor(config) {
20
+ this.config = config;
21
+ }
22
+ exchangeCode(code) {
23
+ return __awaiter(this, void 0, void 0, function* () {
24
+ const tokenResponse = yield (0, isomorphic_unfetch_1.default)('https://connect.mail.ru/oauth/token', {
25
+ method: 'POST',
26
+ headers: { 'Content-Type': 'application/x-www-form-urlencoded' },
27
+ body: `grant_type=authorization_code&client_id=${this.config.clientId}&client_secret=${this.config.clientSecret}&code=${code}&redirect_uri=${this.config.redirectUri}`,
28
+ });
29
+ const tokenData = yield tokenResponse.json();
30
+ if (!tokenData.access_token || !tokenData.x_mailru_vid) {
31
+ throw new Error(`Mail.ru OAuth error: ${tokenData.error_description || tokenData.error || 'no token'}`);
32
+ }
33
+ const mailRuId = tokenData.x_mailru_vid;
34
+ const sig = `app_id=${this.config.clientId}method=users.getInfosecure=1uids=${mailRuId}${this.config.clientSecret}`;
35
+ const md5Sig = crypto_1.default.createHash('md5').update(sig).digest('hex');
36
+ const infoUrl = `https://www.appsmail.ru/platform/api?sig=${md5Sig}&app_id=${this.config.clientId}&method=users.getInfo&secure=1&uids=${mailRuId}`;
37
+ const userResponse = yield (0, isomorphic_unfetch_1.default)(infoUrl);
38
+ const userData = yield userResponse.json();
39
+ const user = Array.isArray(userData) ? userData[0] : null;
40
+ if (!user) {
41
+ throw new Error('Mail.ru OAuth: failed to get user profile');
42
+ }
43
+ const hasAvatar = user.has_pic === 1;
44
+ return {
45
+ providerId: String(mailRuId),
46
+ email: user.email || null,
47
+ name: user.first_name || null,
48
+ avatarUrl: hasAvatar ? user.pic_big : null,
49
+ };
50
+ });
51
+ }
52
+ }
53
+ exports.MailOauth = MailOauth;
@@ -0,0 +1,9 @@
1
+ export interface OAuthProfile {
2
+ providerId: string;
3
+ email?: string | null;
4
+ name?: string | null;
5
+ avatarUrl?: string | null;
6
+ }
7
+ export interface OAuthProvider {
8
+ exchangeCode(code: string): Promise<OAuthProfile>;
9
+ }
@@ -0,0 +1,2 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
@@ -0,0 +1,12 @@
1
+ import { OAuthProfile, OAuthProvider } from './OAuthProvider';
2
+ interface VKOauthConfig {
3
+ clientId: string;
4
+ clientSecret: string;
5
+ redirectUri: string;
6
+ }
7
+ export declare class VKOauth implements OAuthProvider {
8
+ private config;
9
+ constructor(config: VKOauthConfig);
10
+ exchangeCode(code: string): Promise<OAuthProfile>;
11
+ }
12
+ export {};
@@ -0,0 +1,47 @@
1
+ "use strict";
2
+ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
3
+ function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
4
+ return new (P || (P = Promise))(function (resolve, reject) {
5
+ function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
6
+ function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
7
+ function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
8
+ step((generator = generator.apply(thisArg, _arguments || [])).next());
9
+ });
10
+ };
11
+ var __importDefault = (this && this.__importDefault) || function (mod) {
12
+ return (mod && mod.__esModule) ? mod : { "default": mod };
13
+ };
14
+ Object.defineProperty(exports, "__esModule", { value: true });
15
+ exports.VKOauth = void 0;
16
+ const isomorphic_unfetch_1 = __importDefault(require("isomorphic-unfetch"));
17
+ class VKOauth {
18
+ constructor(config) {
19
+ this.config = config;
20
+ }
21
+ exchangeCode(code) {
22
+ return __awaiter(this, void 0, void 0, function* () {
23
+ var _a;
24
+ const tokenResponse = yield (0, isomorphic_unfetch_1.default)(`https://oauth.vk.com/access_token?client_id=${this.config.clientId}&client_secret=${this.config.clientSecret}&redirect_uri=${this.config.redirectUri}&code=${code}`);
25
+ const tokenData = yield tokenResponse.json();
26
+ if (tokenData.error) {
27
+ throw new Error(`VK OAuth error: ${tokenData.error_description || tokenData.error}`);
28
+ }
29
+ if (!tokenData.access_token || !tokenData.user_id) {
30
+ throw new Error('VK OAuth: failed to get access token');
31
+ }
32
+ const userResponse = yield (0, isomorphic_unfetch_1.default)(`https://api.vk.com/method/users.get?user_ids=${tokenData.user_id}&fields=photo_200&access_token=${tokenData.access_token}&v=5.131`);
33
+ const userData = yield userResponse.json();
34
+ const user = (_a = userData.response) === null || _a === void 0 ? void 0 : _a[0];
35
+ if (!user) {
36
+ throw new Error('VK OAuth: failed to get user profile');
37
+ }
38
+ return {
39
+ providerId: String(tokenData.user_id),
40
+ email: tokenData.email || null,
41
+ name: user.first_name || null,
42
+ avatarUrl: user.photo_200 || null,
43
+ };
44
+ });
45
+ }
46
+ }
47
+ exports.VKOauth = VKOauth;
@@ -0,0 +1,11 @@
1
+ import { OAuthProfile, OAuthProvider } from './OAuthProvider';
2
+ interface YandexOauthConfig {
3
+ clientId: string;
4
+ clientSecret: string;
5
+ }
6
+ export declare class YandexOauth implements OAuthProvider {
7
+ private config;
8
+ constructor(config: YandexOauthConfig);
9
+ exchangeCode(code: string): Promise<OAuthProfile>;
10
+ }
11
+ export {};
@@ -0,0 +1,56 @@
1
+ "use strict";
2
+ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
3
+ function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
4
+ return new (P || (P = Promise))(function (resolve, reject) {
5
+ function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
6
+ function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
7
+ function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
8
+ step((generator = generator.apply(thisArg, _arguments || [])).next());
9
+ });
10
+ };
11
+ var __importDefault = (this && this.__importDefault) || function (mod) {
12
+ return (mod && mod.__esModule) ? mod : { "default": mod };
13
+ };
14
+ Object.defineProperty(exports, "__esModule", { value: true });
15
+ exports.YandexOauth = void 0;
16
+ const isomorphic_unfetch_1 = __importDefault(require("isomorphic-unfetch"));
17
+ class YandexOauth {
18
+ constructor(config) {
19
+ this.config = config;
20
+ }
21
+ exchangeCode(code) {
22
+ return __awaiter(this, void 0, void 0, function* () {
23
+ const tokenResponse = yield (0, isomorphic_unfetch_1.default)('https://oauth.yandex.ru/token', {
24
+ method: 'POST',
25
+ headers: { 'Content-Type': 'application/x-www-form-urlencoded' },
26
+ body: `grant_type=authorization_code&client_id=${this.config.clientId}&client_secret=${this.config.clientSecret}&code=${code}`,
27
+ });
28
+ const tokenData = yield tokenResponse.json();
29
+ if (!tokenData.access_token) {
30
+ throw new Error(`Yandex OAuth error: ${tokenData.error_description || tokenData.error}`);
31
+ }
32
+ const userResponse = yield (0, isomorphic_unfetch_1.default)('https://login.yandex.ru/info', {
33
+ method: 'POST',
34
+ headers: {
35
+ Authorization: `OAuth ${tokenData.access_token}`,
36
+ 'Content-Type': 'application/x-www-form-urlencoded',
37
+ },
38
+ body: 'format=json',
39
+ });
40
+ const user = yield userResponse.json();
41
+ if (!user.id) {
42
+ throw new Error('Yandex OAuth: failed to get user profile');
43
+ }
44
+ const avatarUrl = !user.is_avatar_empty
45
+ ? `https://avatars.yandex.net/get-yapic/${user.default_avatar_id}/islands-200`
46
+ : null;
47
+ return {
48
+ providerId: String(user.id),
49
+ email: user.default_email || null,
50
+ name: user.first_name || null,
51
+ avatarUrl,
52
+ };
53
+ });
54
+ }
55
+ }
56
+ exports.YandexOauth = YandexOauth;
@@ -0,0 +1,6 @@
1
+ export * from './OAuthProvider';
2
+ export * from './GoogleOauth';
3
+ export * from './VKOauth';
4
+ export * from './YandexOauth';
5
+ export * from './MailOauth';
6
+ export * from './AppleOauth';
@@ -0,0 +1,22 @@
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 __exportStar = (this && this.__exportStar) || function(m, exports) {
14
+ for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
15
+ };
16
+ Object.defineProperty(exports, "__esModule", { value: true });
17
+ __exportStar(require("./OAuthProvider"), exports);
18
+ __exportStar(require("./GoogleOauth"), exports);
19
+ __exportStar(require("./VKOauth"), exports);
20
+ __exportStar(require("./YandexOauth"), exports);
21
+ __exportStar(require("./MailOauth"), exports);
22
+ __exportStar(require("./AppleOauth"), exports);
@@ -0,0 +1,12 @@
1
+ import { ProfileAuthService } from '../services/ProfileAuthService';
2
+ import { OAuthProvider } from '../oauth/OAuthProvider';
3
+ import { ProfileContext } from '../types';
4
+ export interface OauthResolverDependencies<TContext extends ProfileContext = ProfileContext> {
5
+ authService: ProfileAuthService | ((ctx: TContext) => ProfileAuthService);
6
+ userType: any;
7
+ providers: Record<string, OAuthProvider>;
8
+ telegramBotToken?: string;
9
+ onUserCreated?: (user: any, ctx: TContext) => Promise<void>;
10
+ onLogin?: (user: any, ctx: TContext) => Promise<void>;
11
+ }
12
+ export declare function createOauthResolver<TContext extends ProfileContext = ProfileContext>(deps: OauthResolverDependencies<TContext>): any;