@devoven/oauth 0.1.0

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 (53) hide show
  1. package/README.md +281 -0
  2. package/dist/application/ports/get-auth-url.port.d.ts +3 -0
  3. package/dist/application/ports/get-auth-url.port.js +3 -0
  4. package/dist/application/ports/get-auth-url.port.js.map +1 -0
  5. package/dist/application/ports/handle-callback.port.d.ts +4 -0
  6. package/dist/application/ports/handle-callback.port.js +3 -0
  7. package/dist/application/ports/handle-callback.port.js.map +1 -0
  8. package/dist/application/ports/oauth-provider.port.d.ts +15 -0
  9. package/dist/application/ports/oauth-provider.port.js +3 -0
  10. package/dist/application/ports/oauth-provider.port.js.map +1 -0
  11. package/dist/application/ports/oauth-state-store.port.d.ts +4 -0
  12. package/dist/application/ports/oauth-state-store.port.js +3 -0
  13. package/dist/application/ports/oauth-state-store.port.js.map +1 -0
  14. package/dist/application/use-cases/get-auth-url.use-case.d.ts +9 -0
  15. package/dist/application/use-cases/get-auth-url.use-case.js +38 -0
  16. package/dist/application/use-cases/get-auth-url.use-case.js.map +1 -0
  17. package/dist/application/use-cases/handle-callback.use-case.d.ts +10 -0
  18. package/dist/application/use-cases/handle-callback.use-case.js +42 -0
  19. package/dist/application/use-cases/handle-callback.use-case.js.map +1 -0
  20. package/dist/domain/entities/oauth-profile.entity.d.ts +16 -0
  21. package/dist/domain/entities/oauth-profile.entity.js +26 -0
  22. package/dist/domain/entities/oauth-profile.entity.js.map +1 -0
  23. package/dist/domain/value-objects/oauth-token.vo.d.ts +15 -0
  24. package/dist/domain/value-objects/oauth-token.vo.js +26 -0
  25. package/dist/domain/value-objects/oauth-token.vo.js.map +1 -0
  26. package/dist/index.d.ts +13 -0
  27. package/dist/index.js +20 -0
  28. package/dist/index.js.map +1 -0
  29. package/dist/infrastructure/providers/google-oauth.provider.d.ts +15 -0
  30. package/dist/infrastructure/providers/google-oauth.provider.js +111 -0
  31. package/dist/infrastructure/providers/google-oauth.provider.js.map +1 -0
  32. package/dist/infrastructure/providers/line-oauth.provider.d.ts +16 -0
  33. package/dist/infrastructure/providers/line-oauth.provider.js +118 -0
  34. package/dist/infrastructure/providers/line-oauth.provider.js.map +1 -0
  35. package/dist/infrastructure/state/in-memory-state-store.d.ts +8 -0
  36. package/dist/infrastructure/state/in-memory-state-store.js +49 -0
  37. package/dist/infrastructure/state/in-memory-state-store.js.map +1 -0
  38. package/dist/oauth.module-definition.d.ts +18 -0
  39. package/dist/oauth.module-definition.js +9 -0
  40. package/dist/oauth.module-definition.js.map +1 -0
  41. package/dist/oauth.module.d.ts +8 -0
  42. package/dist/oauth.module.js +102 -0
  43. package/dist/oauth.module.js.map +1 -0
  44. package/dist/presentation/controllers/oauth.controller.d.ts +17 -0
  45. package/dist/presentation/controllers/oauth.controller.js +73 -0
  46. package/dist/presentation/controllers/oauth.controller.js.map +1 -0
  47. package/dist/presentation/dto/oauth-callback-query.dto.d.ts +4 -0
  48. package/dist/presentation/dto/oauth-callback-query.dto.js +27 -0
  49. package/dist/presentation/dto/oauth-callback-query.dto.js.map +1 -0
  50. package/dist/presentation/dto/oauth-profile-response.dto.d.ts +9 -0
  51. package/dist/presentation/dto/oauth-profile-response.dto.js +16 -0
  52. package/dist/presentation/dto/oauth-profile-response.dto.js.map +1 -0
  53. package/package.json +50 -0
@@ -0,0 +1,111 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.GoogleOAuthProvider = void 0;
4
+ const google_auth_library_1 = require("google-auth-library");
5
+ const oauth_profile_entity_1 = require("../../domain/entities/oauth-profile.entity");
6
+ const oauth_token_vo_1 = require("../../domain/value-objects/oauth-token.vo");
7
+ class GoogleOAuthProvider {
8
+ constructor(props) {
9
+ this.name = 'google';
10
+ this.AUTHORIZE_URL = 'https://accounts.google.com/o/oauth2/v2/auth';
11
+ this.TOKEN_URL = 'https://oauth2.googleapis.com/token';
12
+ this.USERINFO_URL = 'https://openidconnect.googleapis.com/v1/userinfo';
13
+ this.props = {
14
+ ...props,
15
+ scopes: props.scopes && props.scopes.length > 0
16
+ ? props.scopes
17
+ : ['openid', 'profile', 'email'],
18
+ };
19
+ this.authClient = new google_auth_library_1.OAuth2Client();
20
+ }
21
+ async getAuthorizationUrl(state) {
22
+ if (!state || state.trim().length === 0) {
23
+ throw new Error('OAuth state is required');
24
+ }
25
+ const params = new URLSearchParams({
26
+ client_id: this.props.clientId,
27
+ redirect_uri: this.props.callbackUrl,
28
+ response_type: 'code',
29
+ scope: this.props.scopes.join(' '),
30
+ state,
31
+ access_type: 'offline',
32
+ include_granted_scopes: 'true',
33
+ prompt: 'consent'
34
+ });
35
+ return `${this.AUTHORIZE_URL}?${params.toString()}`;
36
+ }
37
+ async exchangeCode(code) {
38
+ if (!code || code.trim().length === 0) {
39
+ throw new Error('Authorization code is required');
40
+ }
41
+ const body = new URLSearchParams({
42
+ code,
43
+ client_id: this.props.clientId,
44
+ client_secret: this.props.clientSecret,
45
+ redirect_uri: this.props.callbackUrl,
46
+ grant_type: 'authorization_code',
47
+ });
48
+ const response = await fetch(this.TOKEN_URL, {
49
+ method: 'POST',
50
+ headers: {
51
+ 'Content-Type': 'application/x-www-form-urlencoded',
52
+ },
53
+ body,
54
+ });
55
+ const data = (await response.json());
56
+ if (!response.ok || !data.access_token) {
57
+ throw new Error(`Google token exchange failed${data.error ? `: ${data.error}` : ''}${data.error_description ? ` - ${data.error_description}` : ''}`);
58
+ }
59
+ return oauth_token_vo_1.OAuthToken.create({
60
+ accessToken: data.access_token,
61
+ refreshToken: data.refresh_token || null,
62
+ expiresIn: data.expires_in || null,
63
+ expiresAt: null,
64
+ idToken: data.id_token || null,
65
+ });
66
+ }
67
+ async getProfile(token) {
68
+ if (!token.accessToken) {
69
+ throw new Error('Access token is required');
70
+ }
71
+ if (token.idToken) {
72
+ const ticket = await this.authClient.verifyIdToken({
73
+ idToken: token.idToken,
74
+ audience: this.props.clientId,
75
+ });
76
+ const payload = ticket.getPayload();
77
+ if (!payload?.sub) {
78
+ throw new Error('Invalid id_token: missing sub');
79
+ }
80
+ return oauth_profile_entity_1.OAuthProfile.create({
81
+ provider: this.name,
82
+ providerId: payload.sub,
83
+ email: payload.email ?? null,
84
+ name: payload.name ?? null,
85
+ avatarUrl: payload.picture ?? null,
86
+ });
87
+ }
88
+ const res = await fetch(this.USERINFO_URL, {
89
+ method: 'GET',
90
+ headers: {
91
+ Authorization: `Bearer ${token.accessToken}`,
92
+ },
93
+ });
94
+ if (!res.ok) {
95
+ throw new Error('Failed to fetch Google user profile');
96
+ }
97
+ const data = (await res.json());
98
+ if (!data.sub) {
99
+ throw new Error('Google profile missing providerId');
100
+ }
101
+ return oauth_profile_entity_1.OAuthProfile.create({
102
+ provider: this.name,
103
+ providerId: data.sub,
104
+ email: data.email ?? null,
105
+ name: data.name ?? null,
106
+ avatarUrl: data.picture ?? null,
107
+ });
108
+ }
109
+ }
110
+ exports.GoogleOAuthProvider = GoogleOAuthProvider;
111
+ //# sourceMappingURL=google-oauth.provider.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"google-oauth.provider.js","sourceRoot":"","sources":["../../../src/infrastructure/providers/google-oauth.provider.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,16 @@
1
+ import { OAuthProviderConfig, OAuthProviderPort } from "../../application/ports/oauth-provider.port";
2
+ import { OAuthProfile } from "../../domain/entities/oauth-profile.entity";
3
+ import { OAuthToken } from "../../domain/value-objects/oauth-token.vo";
4
+ export declare class LineOAuthProvider<T extends OAuthProviderConfig = OAuthProviderConfig> implements OAuthProviderPort {
5
+ readonly name = "line";
6
+ private readonly AUTHORIZE_URL;
7
+ private readonly TOKEN_URL;
8
+ private readonly VERIFY_URL;
9
+ private readonly USERINFO_URL;
10
+ protected readonly props: T;
11
+ constructor(props: T);
12
+ getAuthorizationUrl(state: string): Promise<string>;
13
+ exchangeCode(code: string): Promise<OAuthToken>;
14
+ getProfile(token: OAuthToken): Promise<OAuthProfile>;
15
+ private verifyIdToken;
16
+ }
@@ -0,0 +1,118 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.LineOAuthProvider = void 0;
4
+ const oauth_profile_entity_1 = require("../../domain/entities/oauth-profile.entity");
5
+ const oauth_token_vo_1 = require("../../domain/value-objects/oauth-token.vo");
6
+ class LineOAuthProvider {
7
+ constructor(props) {
8
+ this.name = 'line';
9
+ this.AUTHORIZE_URL = 'https://access.line.me/oauth2/v2.1/authorize';
10
+ this.TOKEN_URL = 'https://api.line.me/oauth2/v2.1/token';
11
+ this.VERIFY_URL = 'https://api.line.me/oauth2/v2.1/verify';
12
+ this.USERINFO_URL = 'https://api.line.me/oauth2/v2.1/userinfo';
13
+ this.props = {
14
+ ...props,
15
+ scopes: props.scopes && props.scopes.length > 0
16
+ ? props.scopes
17
+ : ['openid', 'profile'],
18
+ };
19
+ }
20
+ async getAuthorizationUrl(state) {
21
+ if (!state || state.trim().length === 0) {
22
+ throw new Error('OAuth state is required');
23
+ }
24
+ const params = new URLSearchParams({
25
+ response_type: 'code',
26
+ client_id: this.props.clientId,
27
+ redirect_uri: this.props.callbackUrl,
28
+ scope: this.props.scopes.join(' '),
29
+ state,
30
+ });
31
+ return `${this.AUTHORIZE_URL}?${params.toString()}`;
32
+ }
33
+ async exchangeCode(code) {
34
+ if (!code || code.trim().length === 0) {
35
+ throw new Error('Authorization code is required');
36
+ }
37
+ const params = new URLSearchParams({
38
+ grant_type: 'authorization_code',
39
+ code,
40
+ redirect_uri: this.props.callbackUrl,
41
+ client_id: this.props.clientId,
42
+ client_secret: this.props.clientSecret,
43
+ });
44
+ const response = await fetch(this.TOKEN_URL, {
45
+ method: 'POST',
46
+ headers: {
47
+ 'Content-Type': 'application/x-www-form-urlencoded',
48
+ },
49
+ body: params.toString(),
50
+ });
51
+ const data = await response.json();
52
+ if (!response.ok || !data.access_token) {
53
+ throw new Error(`LINE token exchange failed${data.error ? `: ${data.error}` : ''}${data.error_description ? ` - ${data.error_description}` : ''}`);
54
+ }
55
+ return oauth_token_vo_1.OAuthToken.create({
56
+ accessToken: data.access_token,
57
+ refreshToken: data.refresh_token || null,
58
+ expiresIn: data.expires_in || null,
59
+ idToken: data.id_token || null,
60
+ expiresAt: null,
61
+ });
62
+ }
63
+ async getProfile(token) {
64
+ if (!token.accessToken) {
65
+ throw new Error('Access token is required');
66
+ }
67
+ if (token.idToken) {
68
+ const payload = await this.verifyIdToken(token.idToken);
69
+ if (!payload.sub) {
70
+ throw new Error('Invalid id_token: missing sub');
71
+ }
72
+ return oauth_profile_entity_1.OAuthProfile.create({
73
+ provider: this.name,
74
+ providerId: payload.sub,
75
+ email: payload.email ?? null,
76
+ name: payload.name ?? null,
77
+ avatarUrl: payload.picture ?? null,
78
+ });
79
+ }
80
+ const response = await fetch(this.USERINFO_URL, {
81
+ headers: {
82
+ Authorization: `Bearer ${token.accessToken}`,
83
+ },
84
+ });
85
+ if (!response.ok) {
86
+ throw new Error(`Failed to fetch user profile: ${response.statusText}`);
87
+ }
88
+ const data = await response.json();
89
+ if (!data.sub) {
90
+ throw new Error('Line profile missing providerId');
91
+ }
92
+ return oauth_profile_entity_1.OAuthProfile.create({
93
+ provider: this.name,
94
+ providerId: data.sub,
95
+ email: data.email ?? null,
96
+ name: data.name ?? null,
97
+ avatarUrl: data.picture ?? null,
98
+ });
99
+ }
100
+ async verifyIdToken(idToken) {
101
+ const params = new URLSearchParams({
102
+ id_token: idToken,
103
+ client_id: this.props.clientId,
104
+ });
105
+ const response = await fetch(this.VERIFY_URL, {
106
+ method: 'POST',
107
+ headers: { 'Content-Type': 'application/x-www-form-urlencoded' },
108
+ body: params.toString(),
109
+ });
110
+ const data = await response.json();
111
+ if (!response.ok) {
112
+ throw new Error(`LINE ID token verification failed${data.error ? `: ${data.error}` : ''}${data.error_description ? ` - ${data.error_description}` : ''}`);
113
+ }
114
+ return data;
115
+ }
116
+ }
117
+ exports.LineOAuthProvider = LineOAuthProvider;
118
+ //# sourceMappingURL=line-oauth.provider.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"line-oauth.provider.js","sourceRoot":"","sources":["../../../src/infrastructure/providers/line-oauth.provider.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,8 @@
1
+ import { OAuthStateStorePort } from "../../application/ports/oauth-state-store.port";
2
+ export declare class InMemoryStateStore implements OAuthStateStorePort {
3
+ private readonly states;
4
+ private static readonly TTL_MS;
5
+ generate(): Promise<string>;
6
+ verify(state: string): Promise<boolean>;
7
+ private cleanup;
8
+ }
@@ -0,0 +1,49 @@
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 InMemoryStateStore_1;
9
+ Object.defineProperty(exports, "__esModule", { value: true });
10
+ exports.InMemoryStateStore = void 0;
11
+ const crypto_1 = require("crypto");
12
+ const common_1 = require("@nestjs/common");
13
+ let InMemoryStateStore = InMemoryStateStore_1 = class InMemoryStateStore {
14
+ constructor() {
15
+ this.states = new Map();
16
+ }
17
+ async generate() {
18
+ this.cleanup();
19
+ const state = (0, crypto_1.randomUUID)();
20
+ const expiresAt = Date.now() + InMemoryStateStore_1.TTL_MS;
21
+ this.states.set(state, expiresAt);
22
+ return state;
23
+ }
24
+ async verify(state) {
25
+ const expiresAt = this.states.get(state);
26
+ if (!expiresAt) {
27
+ return false;
28
+ }
29
+ this.states.delete(state);
30
+ if (Date.now() > expiresAt) {
31
+ return false;
32
+ }
33
+ return true;
34
+ }
35
+ cleanup() {
36
+ const now = Date.now();
37
+ for (const [state, expiresAt] of this.states.entries()) {
38
+ if (expiresAt <= now) {
39
+ this.states.delete(state);
40
+ }
41
+ }
42
+ }
43
+ };
44
+ exports.InMemoryStateStore = InMemoryStateStore;
45
+ InMemoryStateStore.TTL_MS = 5 * 60 * 1000;
46
+ exports.InMemoryStateStore = InMemoryStateStore = InMemoryStateStore_1 = __decorate([
47
+ (0, common_1.Injectable)()
48
+ ], InMemoryStateStore);
49
+ //# sourceMappingURL=in-memory-state-store.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"in-memory-state-store.js","sourceRoot":"","sources":["../../../src/infrastructure/state/in-memory-state-store.ts"],"names":[],"mappings":";;;;;;;;;;AAAA,mCAAoC;AAEpC,2CAA4C;AAGrC,IAAM,kBAAkB,0BAAxB,MAAM,kBAAkB;IAAxB;QACc,WAAM,GAAG,IAAI,GAAG,EAAkB,CAAC;IAuCxD,CAAC;IApCG,KAAK,CAAC,QAAQ;QACV,IAAI,CAAC,OAAO,EAAE,CAAC;QAEf,MAAM,KAAK,GAAG,IAAA,mBAAU,GAAE,CAAC;QAC3B,MAAM,SAAS,GAAG,IAAI,CAAC,GAAG,EAAE,GAAG,oBAAkB,CAAC,MAAM,CAAC;QAEzD,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,KAAK,EAAE,SAAS,CAAC,CAAC;QAElC,OAAO,KAAK,CAAC;IACjB,CAAC;IAED,KAAK,CAAC,MAAM,CAAC,KAAa;QACtB,MAAM,SAAS,GAAG,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC;QAEzC,IAAI,CAAC,SAAS,EAAE,CAAC;YACb,OAAO,KAAK,CAAC;QACjB,CAAC;QAED,IAAI,CAAC,MAAM,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;QAE1B,IAAI,IAAI,CAAC,GAAG,EAAE,GAAG,SAAS,EAAE,CAAC;YACzB,OAAO,KAAK,CAAC;QACjB,CAAC;QAED,OAAO,IAAI,CAAC;IAChB,CAAC;IAEO,OAAO;QACX,MAAM,GAAG,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;QAEvB,KAAK,MAAM,CAAC,KAAK,EAAE,SAAS,CAAC,IAAI,IAAI,CAAC,MAAM,CAAC,OAAO,EAAE,EAAE,CAAC;YACrD,IAAI,SAAS,IAAI,GAAG,EAAE,CAAC;gBACnB,IAAI,CAAC,MAAM,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;YAC9B,CAAC;QACL,CAAC;IACL,CAAC;;AAvCQ,gDAAkB;AAEH,yBAAM,GAAG,CAAC,GAAG,EAAE,GAAG,IAAI,AAAhB,CAAiB;6BAFtC,kBAAkB;IAD9B,IAAA,mBAAU,GAAE;GACA,kBAAkB,CAwC9B"}
@@ -0,0 +1,18 @@
1
+ import { Type } from '@nestjs/common';
2
+ import { OAuthProviderConfig, OAuthProviderPort } from './application/ports/oauth-provider.port';
3
+ import { OAuthStateStorePort } from './application/ports/oauth-state-store.port';
4
+ export interface OAuthProviderOption {
5
+ name: string;
6
+ provider: new (config: OAuthProviderConfig) => OAuthProviderPort;
7
+ clientId: string;
8
+ clientSecret: string;
9
+ callbackUrl: string;
10
+ scopes?: string[];
11
+ }
12
+ export interface OAuthModuleOptions {
13
+ providers: Array<OAuthProviderOption | OAuthProviderPort>;
14
+ stateStore?: Type<OAuthStateStorePort> | OAuthStateStorePort;
15
+ controller?: boolean;
16
+ callbackSuccessUrl?: string;
17
+ }
18
+ export declare const ConfigurableModuleClass: import("@nestjs/common").ConfigurableModuleCls<OAuthModuleOptions, "register", "create", {}>, MODULE_OPTIONS_TOKEN: string | symbol;
@@ -0,0 +1,9 @@
1
+ "use strict";
2
+ var _a;
3
+ Object.defineProperty(exports, "__esModule", { value: true });
4
+ exports.MODULE_OPTIONS_TOKEN = exports.ConfigurableModuleClass = void 0;
5
+ const common_1 = require("@nestjs/common");
6
+ _a = new common_1.ConfigurableModuleBuilder()
7
+ .setClassMethodName('register')
8
+ .build(), exports.ConfigurableModuleClass = _a.ConfigurableModuleClass, exports.MODULE_OPTIONS_TOKEN = _a.MODULE_OPTIONS_TOKEN;
9
+ //# sourceMappingURL=oauth.module-definition.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"oauth.module-definition.js","sourceRoot":"","sources":["../src/oauth.module-definition.ts"],"names":[],"mappings":";;;;AAAA,2CAAgE;AAoBnD,KACT,IAAI,kCAAyB,EAAsB;KAC9C,kBAAkB,CAAC,UAAU,CAAC;KAC9B,KAAK,EAAE,EAHD,+BAAuB,+BAAE,4BAAoB,2BAG5C"}
@@ -0,0 +1,8 @@
1
+ import { DynamicModule } from '@nestjs/common';
2
+ import { ConfigurableModuleClass, OAuthModuleOptions } from './oauth.module-definition';
3
+ export declare class OAuthModule extends ConfigurableModuleClass {
4
+ static register(options: OAuthModuleOptions): DynamicModule;
5
+ static registerAsync(options: Parameters<typeof ConfigurableModuleClass.registerAsync>[0] & {
6
+ controller?: boolean;
7
+ }): DynamicModule;
8
+ }
@@ -0,0 +1,102 @@
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
+ Object.defineProperty(exports, "__esModule", { value: true });
9
+ exports.OAuthModule = void 0;
10
+ const common_1 = require("@nestjs/common");
11
+ const oauth_module_definition_1 = require("./oauth.module-definition");
12
+ const oauth_controller_1 = require("./presentation/controllers/oauth.controller");
13
+ const get_auth_url_use_case_1 = require("./application/use-cases/get-auth-url.use-case");
14
+ const handle_callback_use_case_1 = require("./application/use-cases/handle-callback.use-case");
15
+ const in_memory_state_store_1 = require("./infrastructure/state/in-memory-state-store");
16
+ function isProviderInstance(p) {
17
+ return typeof p.getAuthorizationUrl === 'function';
18
+ }
19
+ function buildRegistry(providers) {
20
+ const registry = new Map();
21
+ for (const p of providers) {
22
+ if (isProviderInstance(p)) {
23
+ registry.set(p.name, p);
24
+ }
25
+ else {
26
+ const instance = new p.provider({
27
+ clientId: p.clientId,
28
+ clientSecret: p.clientSecret,
29
+ callbackUrl: p.callbackUrl,
30
+ scopes: p.scopes ?? [],
31
+ });
32
+ registry.set(p.name, instance);
33
+ }
34
+ }
35
+ return registry;
36
+ }
37
+ function buildStateStoreProvider(stateStore) {
38
+ if (!stateStore) {
39
+ return { provide: 'OAuthStateStorePort', useClass: in_memory_state_store_1.InMemoryStateStore };
40
+ }
41
+ if (typeof stateStore === 'function') {
42
+ return { provide: 'OAuthStateStorePort', useClass: stateStore };
43
+ }
44
+ return { provide: 'OAuthStateStorePort', useValue: stateStore };
45
+ }
46
+ const USE_CASE_PROVIDERS = [
47
+ { provide: 'GetAuthorizationUrlPort', useClass: get_auth_url_use_case_1.GetAuthorizationUrlUseCase },
48
+ { provide: 'HandleCallbackPort', useClass: handle_callback_use_case_1.HandleCallbackUseCase },
49
+ ];
50
+ const EXPORTED_TOKENS = ['GetAuthorizationUrlPort', 'HandleCallbackPort'];
51
+ let OAuthModule = class OAuthModule extends oauth_module_definition_1.ConfigurableModuleClass {
52
+ static register(options) {
53
+ const { providers = [], ...rest } = super.register(options);
54
+ const controllers = options.controller !== false ? [oauth_controller_1.OAuthController] : [];
55
+ return {
56
+ ...rest,
57
+ controllers,
58
+ providers: [
59
+ ...providers,
60
+ ...USE_CASE_PROVIDERS,
61
+ { provide: 'OAuthProviderRegistry', useValue: buildRegistry(options.providers) },
62
+ buildStateStoreProvider(options.stateStore),
63
+ ],
64
+ exports: EXPORTED_TOKENS,
65
+ };
66
+ }
67
+ static registerAsync(options) {
68
+ const { providers = [], ...rest } = super.registerAsync(options);
69
+ const controllers = options.controller !== false ? [oauth_controller_1.OAuthController] : [];
70
+ return {
71
+ ...rest,
72
+ controllers,
73
+ providers: [
74
+ ...providers,
75
+ ...USE_CASE_PROVIDERS,
76
+ {
77
+ provide: 'OAuthProviderRegistry',
78
+ useFactory: (moduleOptions) => buildRegistry(moduleOptions.providers),
79
+ inject: [oauth_module_definition_1.MODULE_OPTIONS_TOKEN],
80
+ },
81
+ {
82
+ provide: 'OAuthStateStorePort',
83
+ useFactory: (moduleOptions) => {
84
+ const ss = moduleOptions.stateStore;
85
+ if (!ss)
86
+ return new in_memory_state_store_1.InMemoryStateStore();
87
+ if (typeof ss === 'function')
88
+ return new ss();
89
+ return ss;
90
+ },
91
+ inject: [oauth_module_definition_1.MODULE_OPTIONS_TOKEN],
92
+ },
93
+ ],
94
+ exports: EXPORTED_TOKENS,
95
+ };
96
+ }
97
+ };
98
+ exports.OAuthModule = OAuthModule;
99
+ exports.OAuthModule = OAuthModule = __decorate([
100
+ (0, common_1.Module)({})
101
+ ], OAuthModule);
102
+ //# sourceMappingURL=oauth.module.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"oauth.module.js","sourceRoot":"","sources":["../src/oauth.module.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,17 @@
1
+ import { GetAuthorizationUrlPort } from "../../application/ports/get-auth-url.port";
2
+ import { HandleCallbackPort } from "../../application/ports/handle-callback.port";
3
+ import { OAuthModuleOptions } from "../../oauth.module-definition";
4
+ import { OAuthCallbackQueryDto } from "../dto/oauth-callback-query.dto";
5
+ import { OAuthProfileResponseDto } from "../dto/oauth-profile-response.dto";
6
+ import { Response } from "express";
7
+ export declare class OAuthController {
8
+ private readonly getAuthorizationUrl;
9
+ private readonly handleCallback;
10
+ private readonly moduleOptions;
11
+ constructor(getAuthorizationUrl: GetAuthorizationUrlPort, handleCallback: HandleCallbackPort, moduleOptions: OAuthModuleOptions | null);
12
+ authorize(provider: string): Promise<{
13
+ url: string;
14
+ statusCode: number;
15
+ }>;
16
+ callback(provider: string, query: OAuthCallbackQueryDto, res: Response): Promise<OAuthProfileResponseDto | undefined>;
17
+ }
@@ -0,0 +1,73 @@
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
+ var __param = (this && this.__param) || function (paramIndex, decorator) {
12
+ return function (target, key) { decorator(target, key, paramIndex); }
13
+ };
14
+ Object.defineProperty(exports, "__esModule", { value: true });
15
+ exports.OAuthController = void 0;
16
+ const common_1 = require("@nestjs/common");
17
+ const oauth_module_definition_1 = require("../../oauth.module-definition");
18
+ const oauth_callback_query_dto_1 = require("../dto/oauth-callback-query.dto");
19
+ const oauth_profile_response_dto_1 = require("../dto/oauth-profile-response.dto");
20
+ let OAuthController = class OAuthController {
21
+ constructor(getAuthorizationUrl, handleCallback, moduleOptions) {
22
+ this.getAuthorizationUrl = getAuthorizationUrl;
23
+ this.handleCallback = handleCallback;
24
+ this.moduleOptions = moduleOptions;
25
+ }
26
+ async authorize(provider) {
27
+ const url = await this.getAuthorizationUrl.execute(provider);
28
+ return { url, statusCode: 302 };
29
+ }
30
+ async callback(provider, query, res) {
31
+ const profile = await this.handleCallback.execute(provider, query.code, query.state);
32
+ const successUrl = this.moduleOptions?.callbackSuccessUrl;
33
+ if (successUrl) {
34
+ const params = new URLSearchParams({
35
+ provider: profile.provider,
36
+ providerId: profile.providerId,
37
+ ...(profile.email && { email: profile.email }),
38
+ ...(profile.name && { name: profile.name }),
39
+ ...(profile.avatarUrl && { avatarUrl: profile.avatarUrl }),
40
+ });
41
+ res.redirect(`${successUrl}?${params.toString()}`);
42
+ return;
43
+ }
44
+ return oauth_profile_response_dto_1.OAuthProfileResponseDto.fromDomain(profile);
45
+ }
46
+ };
47
+ exports.OAuthController = OAuthController;
48
+ __decorate([
49
+ (0, common_1.Get)(":provider"),
50
+ (0, common_1.Redirect)(),
51
+ __param(0, (0, common_1.Param)("provider")),
52
+ __metadata("design:type", Function),
53
+ __metadata("design:paramtypes", [String]),
54
+ __metadata("design:returntype", Promise)
55
+ ], OAuthController.prototype, "authorize", null);
56
+ __decorate([
57
+ (0, common_1.Get)(":provider/callback"),
58
+ __param(0, (0, common_1.Param)("provider")),
59
+ __param(1, (0, common_1.Query)()),
60
+ __param(2, (0, common_1.Res)({ passthrough: true })),
61
+ __metadata("design:type", Function),
62
+ __metadata("design:paramtypes", [String, oauth_callback_query_dto_1.OAuthCallbackQueryDto, Object]),
63
+ __metadata("design:returntype", Promise)
64
+ ], OAuthController.prototype, "callback", null);
65
+ exports.OAuthController = OAuthController = __decorate([
66
+ (0, common_1.Controller)("oauth"),
67
+ __param(0, (0, common_1.Inject)("GetAuthorizationUrlPort")),
68
+ __param(1, (0, common_1.Inject)("HandleCallbackPort")),
69
+ __param(2, (0, common_1.Optional)()),
70
+ __param(2, (0, common_1.Inject)(oauth_module_definition_1.MODULE_OPTIONS_TOKEN)),
71
+ __metadata("design:paramtypes", [Object, Object, Object])
72
+ ], OAuthController);
73
+ //# sourceMappingURL=oauth.controller.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"oauth.controller.js","sourceRoot":"","sources":["../../../src/presentation/controllers/oauth.controller.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;AAAA,2CASwB;AAGxB,2EAGuC;AACvC,8EAAwE;AACxE,kFAA4E;AAIrE,IAAM,eAAe,GAArB,MAAM,eAAe;IAC1B,YAEmB,mBAA4C,EAG5C,cAAkC,EAIlC,aAAwC;QAPxC,wBAAmB,GAAnB,mBAAmB,CAAyB;QAG5C,mBAAc,GAAd,cAAc,CAAoB;QAIlC,kBAAa,GAAb,aAAa,CAA2B;IACxD,CAAC;IAIE,AAAN,KAAK,CAAC,SAAS,CAAoB,QAAgB;QACjD,MAAM,GAAG,GAAG,MAAM,IAAI,CAAC,mBAAmB,CAAC,OAAO,CAAC,QAAQ,CAAC,CAAC;QAC7D,OAAO,EAAE,GAAG,EAAE,UAAU,EAAE,GAAG,EAAE,CAAC;IAClC,CAAC;IAGK,AAAN,KAAK,CAAC,QAAQ,CACO,QAAgB,EAC1B,KAA4B,EACT,GAAa;QAEzC,MAAM,OAAO,GAAG,MAAM,IAAI,CAAC,cAAc,CAAC,OAAO,CAC/C,QAAQ,EACR,KAAK,CAAC,IAAI,EACV,KAAK,CAAC,KAAK,CACZ,CAAC;QAEF,MAAM,UAAU,GAAG,IAAI,CAAC,aAAa,EAAE,kBAAkB,CAAC;QAC1D,IAAI,UAAU,EAAE,CAAC;YACf,MAAM,MAAM,GAAG,IAAI,eAAe,CAAC;gBACjC,QAAQ,EAAE,OAAO,CAAC,QAAQ;gBAC1B,UAAU,EAAE,OAAO,CAAC,UAAU;gBAC9B,GAAG,CAAC,OAAO,CAAC,KAAK,IAAI,EAAE,KAAK,EAAE,OAAO,CAAC,KAAK,EAAE,CAAC;gBAC9C,GAAG,CAAC,OAAO,CAAC,IAAI,IAAI,EAAE,IAAI,EAAE,OAAO,CAAC,IAAI,EAAE,CAAC;gBAC3C,GAAG,CAAC,OAAO,CAAC,SAAS,IAAI,EAAE,SAAS,EAAE,OAAO,CAAC,SAAS,EAAE,CAAC;aAC3D,CAAC,CAAC;YACH,GAAG,CAAC,QAAQ,CAAC,GAAG,UAAU,IAAI,MAAM,CAAC,QAAQ,EAAE,EAAE,CAAC,CAAC;YACnD,OAAO;QACT,CAAC;QAED,OAAO,oDAAuB,CAAC,UAAU,CAAC,OAAO,CAAC,CAAC;IACrD,CAAC;CACF,CAAA;AA/CY,0CAAe;AAepB;IAFL,IAAA,YAAG,EAAC,WAAW,CAAC;IAChB,IAAA,iBAAQ,GAAE;IACM,WAAA,IAAA,cAAK,EAAC,UAAU,CAAC,CAAA;;;;gDAGjC;AAGK;IADL,IAAA,YAAG,EAAC,oBAAoB,CAAC;IAEvB,WAAA,IAAA,cAAK,EAAC,UAAU,CAAC,CAAA;IACjB,WAAA,IAAA,cAAK,GAAE,CAAA;IACP,WAAA,IAAA,YAAG,EAAC,EAAE,WAAW,EAAE,IAAI,EAAE,CAAC,CAAA;;6CADX,gDAAqB;;+CAuBtC;0BA9CU,eAAe;IAD3B,IAAA,mBAAU,EAAC,OAAO,CAAC;IAGf,WAAA,IAAA,eAAM,EAAC,yBAAyB,CAAC,CAAA;IAGjC,WAAA,IAAA,eAAM,EAAC,oBAAoB,CAAC,CAAA;IAG5B,WAAA,IAAA,iBAAQ,GAAE,CAAA;IACV,WAAA,IAAA,eAAM,EAAC,8CAAoB,CAAC,CAAA;;GATpB,eAAe,CA+C3B"}
@@ -0,0 +1,4 @@
1
+ export declare class OAuthCallbackQueryDto {
2
+ code: string;
3
+ state: string;
4
+ }
@@ -0,0 +1,27 @@
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.OAuthCallbackQueryDto = void 0;
13
+ const class_validator_1 = require("class-validator");
14
+ class OAuthCallbackQueryDto {
15
+ }
16
+ exports.OAuthCallbackQueryDto = OAuthCallbackQueryDto;
17
+ __decorate([
18
+ (0, class_validator_1.IsString)(),
19
+ (0, class_validator_1.IsNotEmpty)(),
20
+ __metadata("design:type", String)
21
+ ], OAuthCallbackQueryDto.prototype, "code", void 0);
22
+ __decorate([
23
+ (0, class_validator_1.IsString)(),
24
+ (0, class_validator_1.IsNotEmpty)(),
25
+ __metadata("design:type", String)
26
+ ], OAuthCallbackQueryDto.prototype, "state", void 0);
27
+ //# sourceMappingURL=oauth-callback-query.dto.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"oauth-callback-query.dto.js","sourceRoot":"","sources":["../../../src/presentation/dto/oauth-callback-query.dto.ts"],"names":[],"mappings":";;;;;;;;;;;;AAAA,qDAAuD;AAEvD,MAAa,qBAAqB;CAQjC;AARD,sDAQC;AALG;IAFC,IAAA,0BAAQ,GAAE;IACV,IAAA,4BAAU,GAAE;;mDACA;AAIb;IAFC,IAAA,0BAAQ,GAAE;IACV,IAAA,4BAAU,GAAE;;oDACC"}
@@ -0,0 +1,9 @@
1
+ import { OAuthProfile } from "../../domain/entities/oauth-profile.entity";
2
+ export declare class OAuthProfileResponseDto {
3
+ provider: string;
4
+ providerId: string;
5
+ email: string | null;
6
+ name: string | null;
7
+ avatarUrl: string | null;
8
+ static fromDomain(profile: OAuthProfile): OAuthProfileResponseDto;
9
+ }
@@ -0,0 +1,16 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.OAuthProfileResponseDto = void 0;
4
+ class OAuthProfileResponseDto {
5
+ static fromDomain(profile) {
6
+ return Object.assign(new OAuthProfileResponseDto(), {
7
+ provider: profile.provider,
8
+ providerId: profile.providerId,
9
+ email: profile.email,
10
+ name: profile.name,
11
+ avatarUrl: profile.avatarUrl,
12
+ });
13
+ }
14
+ }
15
+ exports.OAuthProfileResponseDto = OAuthProfileResponseDto;
16
+ //# sourceMappingURL=oauth-profile-response.dto.js.map