@bactv/socialite 1.0.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 (62) hide show
  1. package/README.md +133 -0
  2. package/dist/application/dto/ProviderConfig.d.ts +23 -0
  3. package/dist/application/dto/ProviderConfig.js +3 -0
  4. package/dist/application/dto/ProviderConfig.js.map +1 -0
  5. package/dist/application/services/SocialiteManager.d.ts +50 -0
  6. package/dist/application/services/SocialiteManager.js +73 -0
  7. package/dist/application/services/SocialiteManager.js.map +1 -0
  8. package/dist/domain/contracts/HttpClientContract.d.ts +12 -0
  9. package/dist/domain/contracts/HttpClientContract.js +3 -0
  10. package/dist/domain/contracts/HttpClientContract.js.map +1 -0
  11. package/dist/domain/contracts/OAuthProviderContract.d.ts +28 -0
  12. package/dist/domain/contracts/OAuthProviderContract.js +3 -0
  13. package/dist/domain/contracts/OAuthProviderContract.js.map +1 -0
  14. package/dist/domain/contracts/StateStoreContract.d.ts +13 -0
  15. package/dist/domain/contracts/StateStoreContract.js +3 -0
  16. package/dist/domain/contracts/StateStoreContract.js.map +1 -0
  17. package/dist/domain/entities/SocialUser.d.ts +36 -0
  18. package/dist/domain/entities/SocialUser.js +33 -0
  19. package/dist/domain/entities/SocialUser.js.map +1 -0
  20. package/dist/domain/errors/SocialiteError.d.ts +18 -0
  21. package/dist/domain/errors/SocialiteError.js +46 -0
  22. package/dist/domain/errors/SocialiteError.js.map +1 -0
  23. package/dist/domain/value-objects/AccessTokenResult.d.ts +16 -0
  24. package/dist/domain/value-objects/AccessTokenResult.js +28 -0
  25. package/dist/domain/value-objects/AccessTokenResult.js.map +1 -0
  26. package/dist/domain/value-objects/ProviderName.d.ts +9 -0
  27. package/dist/domain/value-objects/ProviderName.js +22 -0
  28. package/dist/domain/value-objects/ProviderName.js.map +1 -0
  29. package/dist/index.d.ts +36 -0
  30. package/dist/index.js +56 -0
  31. package/dist/index.js.map +1 -0
  32. package/dist/infrastructure/http/FetchHttpClient.d.ts +13 -0
  33. package/dist/infrastructure/http/FetchHttpClient.js +58 -0
  34. package/dist/infrastructure/http/FetchHttpClient.js.map +1 -0
  35. package/dist/infrastructure/http/MemoryStateStore.d.ts +15 -0
  36. package/dist/infrastructure/http/MemoryStateStore.js +29 -0
  37. package/dist/infrastructure/http/MemoryStateStore.js.map +1 -0
  38. package/dist/infrastructure/providers/AbstractProvider.d.ts +39 -0
  39. package/dist/infrastructure/providers/AbstractProvider.js +98 -0
  40. package/dist/infrastructure/providers/AbstractProvider.js.map +1 -0
  41. package/dist/infrastructure/providers/FacebookProvider.d.ts +14 -0
  42. package/dist/infrastructure/providers/FacebookProvider.js +55 -0
  43. package/dist/infrastructure/providers/FacebookProvider.js.map +1 -0
  44. package/dist/infrastructure/providers/GithubProvider.d.ts +12 -0
  45. package/dist/infrastructure/providers/GithubProvider.js +55 -0
  46. package/dist/infrastructure/providers/GithubProvider.js.map +1 -0
  47. package/dist/infrastructure/providers/GoogleProvider.d.ts +11 -0
  48. package/dist/infrastructure/providers/GoogleProvider.js +31 -0
  49. package/dist/infrastructure/providers/GoogleProvider.js.map +1 -0
  50. package/dist/infrastructure/providers/LinkedinProvider.d.ts +11 -0
  51. package/dist/infrastructure/providers/LinkedinProvider.js +33 -0
  52. package/dist/infrastructure/providers/LinkedinProvider.js.map +1 -0
  53. package/dist/infrastructure/providers/MicrosoftProvider.d.ts +11 -0
  54. package/dist/infrastructure/providers/MicrosoftProvider.js +32 -0
  55. package/dist/infrastructure/providers/MicrosoftProvider.js.map +1 -0
  56. package/dist/infrastructure/providers/ProviderFactory.d.ts +15 -0
  57. package/dist/infrastructure/providers/ProviderFactory.js +36 -0
  58. package/dist/infrastructure/providers/ProviderFactory.js.map +1 -0
  59. package/dist/infrastructure/providers/TwitterProvider.d.ts +13 -0
  60. package/dist/infrastructure/providers/TwitterProvider.js +43 -0
  61. package/dist/infrastructure/providers/TwitterProvider.js.map +1 -0
  62. package/package.json +47 -0
package/dist/index.js ADDED
@@ -0,0 +1,56 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.LinkedinProvider = exports.TwitterProvider = exports.GithubProvider = exports.FacebookProvider = exports.MicrosoftProvider = exports.GoogleProvider = exports.ProviderFactory = exports.MemoryStateStore = exports.FetchHttpClient = exports.SocialiteManager = exports.UserFetchError = exports.TokenExchangeError = exports.UnsupportedProviderError = exports.ProviderNotConfiguredError = exports.InvalidStateError = exports.SocialiteError = exports.isSupportedProvider = exports.SUPPORTED_PROVIDERS = exports.AccessTokenResult = exports.SocialUser = exports.Socialite = void 0;
4
+ const SocialiteManager_1 = require("./application/services/SocialiteManager");
5
+ /**
6
+ * Socialite -- public factory.
7
+ *
8
+ * const socialite = Socialite.create({
9
+ * google: { clientId, clientSecret, redirectUri },
10
+ * github: { clientId, clientSecret, redirectUri },
11
+ * });
12
+ */
13
+ class Socialite {
14
+ static create(config, http, stateStore) {
15
+ return new SocialiteManager_1.SocialiteManager(config, http, stateStore);
16
+ }
17
+ }
18
+ exports.Socialite = Socialite;
19
+ // Domain
20
+ var SocialUser_1 = require("./domain/entities/SocialUser");
21
+ Object.defineProperty(exports, "SocialUser", { enumerable: true, get: function () { return SocialUser_1.SocialUser; } });
22
+ var AccessTokenResult_1 = require("./domain/value-objects/AccessTokenResult");
23
+ Object.defineProperty(exports, "AccessTokenResult", { enumerable: true, get: function () { return AccessTokenResult_1.AccessTokenResult; } });
24
+ var ProviderName_1 = require("./domain/value-objects/ProviderName");
25
+ Object.defineProperty(exports, "SUPPORTED_PROVIDERS", { enumerable: true, get: function () { return ProviderName_1.SUPPORTED_PROVIDERS; } });
26
+ Object.defineProperty(exports, "isSupportedProvider", { enumerable: true, get: function () { return ProviderName_1.isSupportedProvider; } });
27
+ var SocialiteError_1 = require("./domain/errors/SocialiteError");
28
+ Object.defineProperty(exports, "SocialiteError", { enumerable: true, get: function () { return SocialiteError_1.SocialiteError; } });
29
+ Object.defineProperty(exports, "InvalidStateError", { enumerable: true, get: function () { return SocialiteError_1.InvalidStateError; } });
30
+ Object.defineProperty(exports, "ProviderNotConfiguredError", { enumerable: true, get: function () { return SocialiteError_1.ProviderNotConfiguredError; } });
31
+ Object.defineProperty(exports, "UnsupportedProviderError", { enumerable: true, get: function () { return SocialiteError_1.UnsupportedProviderError; } });
32
+ Object.defineProperty(exports, "TokenExchangeError", { enumerable: true, get: function () { return SocialiteError_1.TokenExchangeError; } });
33
+ Object.defineProperty(exports, "UserFetchError", { enumerable: true, get: function () { return SocialiteError_1.UserFetchError; } });
34
+ // Application
35
+ var SocialiteManager_2 = require("./application/services/SocialiteManager");
36
+ Object.defineProperty(exports, "SocialiteManager", { enumerable: true, get: function () { return SocialiteManager_2.SocialiteManager; } });
37
+ // Infrastructure (exported for advanced consumers who want to swap adapters)
38
+ var FetchHttpClient_1 = require("./infrastructure/http/FetchHttpClient");
39
+ Object.defineProperty(exports, "FetchHttpClient", { enumerable: true, get: function () { return FetchHttpClient_1.FetchHttpClient; } });
40
+ var MemoryStateStore_1 = require("./infrastructure/http/MemoryStateStore");
41
+ Object.defineProperty(exports, "MemoryStateStore", { enumerable: true, get: function () { return MemoryStateStore_1.MemoryStateStore; } });
42
+ var ProviderFactory_1 = require("./infrastructure/providers/ProviderFactory");
43
+ Object.defineProperty(exports, "ProviderFactory", { enumerable: true, get: function () { return ProviderFactory_1.ProviderFactory; } });
44
+ var GoogleProvider_1 = require("./infrastructure/providers/GoogleProvider");
45
+ Object.defineProperty(exports, "GoogleProvider", { enumerable: true, get: function () { return GoogleProvider_1.GoogleProvider; } });
46
+ var MicrosoftProvider_1 = require("./infrastructure/providers/MicrosoftProvider");
47
+ Object.defineProperty(exports, "MicrosoftProvider", { enumerable: true, get: function () { return MicrosoftProvider_1.MicrosoftProvider; } });
48
+ var FacebookProvider_1 = require("./infrastructure/providers/FacebookProvider");
49
+ Object.defineProperty(exports, "FacebookProvider", { enumerable: true, get: function () { return FacebookProvider_1.FacebookProvider; } });
50
+ var GithubProvider_1 = require("./infrastructure/providers/GithubProvider");
51
+ Object.defineProperty(exports, "GithubProvider", { enumerable: true, get: function () { return GithubProvider_1.GithubProvider; } });
52
+ var TwitterProvider_1 = require("./infrastructure/providers/TwitterProvider");
53
+ Object.defineProperty(exports, "TwitterProvider", { enumerable: true, get: function () { return TwitterProvider_1.TwitterProvider; } });
54
+ var LinkedinProvider_1 = require("./infrastructure/providers/LinkedinProvider");
55
+ Object.defineProperty(exports, "LinkedinProvider", { enumerable: true, get: function () { return LinkedinProvider_1.LinkedinProvider; } });
56
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";;;AACA,8EAA2E;AAI3E;;;;;;;GAOG;AACH,MAAa,SAAS;IACpB,MAAM,CAAC,MAAM,CAAC,MAAuB,EAAE,IAAyB,EAAE,UAA+B;QAC/F,OAAO,IAAI,mCAAgB,CAAC,MAAM,EAAE,IAAI,EAAE,UAAU,CAAC,CAAC;IACxD,CAAC;CACF;AAJD,8BAIC;AAED,SAAS;AACT,2DAA0D;AAAjD,wGAAA,UAAU,OAAA;AAEnB,8EAA6E;AAApE,sHAAA,iBAAiB,OAAA;AAC1B,oEAA+F;AAAtF,mHAAA,mBAAmB,OAAA;AAAE,mHAAA,mBAAmB,OAAA;AAKjD,iEAOwC;AANtC,gHAAA,cAAc,OAAA;AACd,mHAAA,iBAAiB,OAAA;AACjB,4HAAA,0BAA0B,OAAA;AAC1B,0HAAA,wBAAwB,OAAA;AACxB,oHAAA,kBAAkB,OAAA;AAClB,gHAAA,cAAc,OAAA;AAGhB,cAAc;AACd,4EAA2E;AAAlE,oHAAA,gBAAgB,OAAA;AAIzB,6EAA6E;AAC7E,yEAAwE;AAA/D,kHAAA,eAAe,OAAA;AACxB,2EAA0E;AAAjE,oHAAA,gBAAgB,OAAA;AACzB,8EAA6E;AAApE,kHAAA,eAAe,OAAA;AACxB,4EAA2E;AAAlE,gHAAA,cAAc,OAAA;AACvB,kFAAiF;AAAxE,sHAAA,iBAAiB,OAAA;AAC1B,gFAA+E;AAAtE,oHAAA,gBAAgB,OAAA;AACzB,4EAA2E;AAAlE,gHAAA,cAAc,OAAA;AACvB,8EAA6E;AAApE,kHAAA,eAAe,OAAA;AACxB,gFAA+E;AAAtE,oHAAA,gBAAgB,OAAA"}
@@ -0,0 +1,13 @@
1
+ import { HttpClientContract } from "../../domain/contracts/HttpClientContract";
2
+ /**
3
+ * Infrastructure Adapter: FetchHttpClient
4
+ *
5
+ * Implements the HttpClientContract port using Node's built-in `fetch`
6
+ * (available globally since Node 18). Swap this for an Axios-based
7
+ * adapter, or a test double, without touching any domain/application code.
8
+ */
9
+ export declare class FetchHttpClient implements HttpClientContract {
10
+ postForm<T = Record<string, unknown>>(url: string, form: Record<string, string>, headers?: Record<string, string>): Promise<T>;
11
+ getJson<T = Record<string, unknown>>(url: string, headers?: Record<string, string>): Promise<T>;
12
+ private safeParseJson;
13
+ }
@@ -0,0 +1,58 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.FetchHttpClient = void 0;
4
+ /**
5
+ * Infrastructure Adapter: FetchHttpClient
6
+ *
7
+ * Implements the HttpClientContract port using Node's built-in `fetch`
8
+ * (available globally since Node 18). Swap this for an Axios-based
9
+ * adapter, or a test double, without touching any domain/application code.
10
+ */
11
+ class FetchHttpClient {
12
+ async postForm(url, form, headers = {}) {
13
+ const body = new URLSearchParams(form).toString();
14
+ const response = await fetch(url, {
15
+ method: "POST",
16
+ headers: {
17
+ "Content-Type": "application/x-www-form-urlencoded",
18
+ Accept: "application/json",
19
+ ...headers,
20
+ },
21
+ body,
22
+ });
23
+ const text = await response.text();
24
+ const parsed = this.safeParseJson(text);
25
+ if (!response.ok) {
26
+ const message = typeof parsed === "object" && parsed !== null ? JSON.stringify(parsed) : text;
27
+ throw new Error(`HTTP ${response.status}: ${message}`);
28
+ }
29
+ return parsed;
30
+ }
31
+ async getJson(url, headers = {}) {
32
+ const response = await fetch(url, {
33
+ method: "GET",
34
+ headers: {
35
+ Accept: "application/json",
36
+ ...headers,
37
+ },
38
+ });
39
+ const text = await response.text();
40
+ const parsed = this.safeParseJson(text);
41
+ if (!response.ok) {
42
+ const message = typeof parsed === "object" && parsed !== null ? JSON.stringify(parsed) : text;
43
+ throw new Error(`HTTP ${response.status}: ${message}`);
44
+ }
45
+ return parsed;
46
+ }
47
+ safeParseJson(text) {
48
+ try {
49
+ return JSON.parse(text);
50
+ }
51
+ catch {
52
+ // Some providers (rarely) respond with form-encoded bodies.
53
+ return Object.fromEntries(new URLSearchParams(text));
54
+ }
55
+ }
56
+ }
57
+ exports.FetchHttpClient = FetchHttpClient;
58
+ //# sourceMappingURL=FetchHttpClient.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"FetchHttpClient.js","sourceRoot":"","sources":["../../../src/infrastructure/http/FetchHttpClient.ts"],"names":[],"mappings":";;;AAEA;;;;;;GAMG;AACH,MAAa,eAAe;IAC1B,KAAK,CAAC,QAAQ,CACZ,GAAW,EACX,IAA4B,EAC5B,UAAkC,EAAE;QAEpC,MAAM,IAAI,GAAG,IAAI,eAAe,CAAC,IAAI,CAAC,CAAC,QAAQ,EAAE,CAAC;QAClD,MAAM,QAAQ,GAAG,MAAM,KAAK,CAAC,GAAG,EAAE;YAChC,MAAM,EAAE,MAAM;YACd,OAAO,EAAE;gBACP,cAAc,EAAE,mCAAmC;gBACnD,MAAM,EAAE,kBAAkB;gBAC1B,GAAG,OAAO;aACX;YACD,IAAI;SACL,CAAC,CAAC;QAEH,MAAM,IAAI,GAAG,MAAM,QAAQ,CAAC,IAAI,EAAE,CAAC;QACnC,MAAM,MAAM,GAAG,IAAI,CAAC,aAAa,CAAC,IAAI,CAAC,CAAC;QAExC,IAAI,CAAC,QAAQ,CAAC,EAAE,EAAE,CAAC;YACjB,MAAM,OAAO,GAAG,OAAO,MAAM,KAAK,QAAQ,IAAI,MAAM,KAAK,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,SAAS,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC;YAC9F,MAAM,IAAI,KAAK,CAAC,QAAQ,QAAQ,CAAC,MAAM,KAAK,OAAO,EAAE,CAAC,CAAC;QACzD,CAAC;QAED,OAAO,MAAW,CAAC;IACrB,CAAC;IAED,KAAK,CAAC,OAAO,CAA8B,GAAW,EAAE,UAAkC,EAAE;QAC1F,MAAM,QAAQ,GAAG,MAAM,KAAK,CAAC,GAAG,EAAE;YAChC,MAAM,EAAE,KAAK;YACb,OAAO,EAAE;gBACP,MAAM,EAAE,kBAAkB;gBAC1B,GAAG,OAAO;aACX;SACF,CAAC,CAAC;QAEH,MAAM,IAAI,GAAG,MAAM,QAAQ,CAAC,IAAI,EAAE,CAAC;QACnC,MAAM,MAAM,GAAG,IAAI,CAAC,aAAa,CAAC,IAAI,CAAC,CAAC;QAExC,IAAI,CAAC,QAAQ,CAAC,EAAE,EAAE,CAAC;YACjB,MAAM,OAAO,GAAG,OAAO,MAAM,KAAK,QAAQ,IAAI,MAAM,KAAK,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,SAAS,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC;YAC9F,MAAM,IAAI,KAAK,CAAC,QAAQ,QAAQ,CAAC,MAAM,KAAK,OAAO,EAAE,CAAC,CAAC;QACzD,CAAC;QAED,OAAO,MAAW,CAAC;IACrB,CAAC;IAEO,aAAa,CAAC,IAAY;QAChC,IAAI,CAAC;YACH,OAAO,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;QAC1B,CAAC;QAAC,MAAM,CAAC;YACP,4DAA4D;YAC5D,OAAO,MAAM,CAAC,WAAW,CAAC,IAAI,eAAe,CAAC,IAAI,CAAC,CAAC,CAAC;QACvD,CAAC;IACH,CAAC;CACF;AAxDD,0CAwDC"}
@@ -0,0 +1,15 @@
1
+ import { StateStoreContract } from "../../domain/contracts/StateStoreContract";
2
+ /**
3
+ * Infrastructure Adapter: MemoryStateStore
4
+ *
5
+ * Default StateStoreContract implementation. Fine for single-process
6
+ * demos/tests; in production, swap in a Redis- or session-backed
7
+ * implementation (multi-instance deployments need shared storage).
8
+ */
9
+ export declare class MemoryStateStore implements StateStoreContract {
10
+ private readonly store;
11
+ private readonly ttlMs;
12
+ constructor(ttlMs?: number);
13
+ put(state: string, codeVerifier: string | null): void;
14
+ pull(state: string): string | null;
15
+ }
@@ -0,0 +1,29 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.MemoryStateStore = void 0;
4
+ /**
5
+ * Infrastructure Adapter: MemoryStateStore
6
+ *
7
+ * Default StateStoreContract implementation. Fine for single-process
8
+ * demos/tests; in production, swap in a Redis- or session-backed
9
+ * implementation (multi-instance deployments need shared storage).
10
+ */
11
+ class MemoryStateStore {
12
+ constructor(ttlMs = 10 * 60 * 1000) {
13
+ this.store = new Map();
14
+ this.ttlMs = ttlMs;
15
+ }
16
+ put(state, codeVerifier) {
17
+ this.store.set(state, { codeVerifier, expiresAt: Date.now() + this.ttlMs });
18
+ }
19
+ pull(state) {
20
+ const entry = this.store.get(state);
21
+ this.store.delete(state);
22
+ if (!entry || entry.expiresAt < Date.now()) {
23
+ return null;
24
+ }
25
+ return entry.codeVerifier;
26
+ }
27
+ }
28
+ exports.MemoryStateStore = MemoryStateStore;
29
+ //# sourceMappingURL=MemoryStateStore.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"MemoryStateStore.js","sourceRoot":"","sources":["../../../src/infrastructure/http/MemoryStateStore.ts"],"names":[],"mappings":";;;AAEA;;;;;;GAMG;AACH,MAAa,gBAAgB;IAI3B,YAAY,KAAK,GAAG,EAAE,GAAG,EAAE,GAAG,IAAI;QAHjB,UAAK,GAAG,IAAI,GAAG,EAA8D,CAAC;QAI7F,IAAI,CAAC,KAAK,GAAG,KAAK,CAAC;IACrB,CAAC;IAED,GAAG,CAAC,KAAa,EAAE,YAA2B;QAC5C,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,KAAK,EAAE,EAAE,YAAY,EAAE,SAAS,EAAE,IAAI,CAAC,GAAG,EAAE,GAAG,IAAI,CAAC,KAAK,EAAE,CAAC,CAAC;IAC9E,CAAC;IAED,IAAI,CAAC,KAAa;QAChB,MAAM,KAAK,GAAG,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC;QACpC,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;QACzB,IAAI,CAAC,KAAK,IAAI,KAAK,CAAC,SAAS,GAAG,IAAI,CAAC,GAAG,EAAE,EAAE,CAAC;YAC3C,OAAO,IAAI,CAAC;QACd,CAAC;QACD,OAAO,KAAK,CAAC,YAAY,CAAC;IAC5B,CAAC;CACF;AApBD,4CAoBC"}
@@ -0,0 +1,39 @@
1
+ import { OAuthProviderContract } from "../../domain/contracts/OAuthProviderContract";
2
+ import { HttpClientContract } from "../../domain/contracts/HttpClientContract";
3
+ import { StateStoreContract } from "../../domain/contracts/StateStoreContract";
4
+ import { AccessTokenResult } from "../../domain/value-objects/AccessTokenResult";
5
+ import { SocialUser } from "../../domain/entities/SocialUser";
6
+ import { ProviderConfig } from "../../application/dto/ProviderConfig";
7
+ /**
8
+ * Infrastructure: AbstractProvider
9
+ *
10
+ * Template-method base class implementing the parts of the OAuth2
11
+ * "authorization code" grant that are identical across providers
12
+ * (building the auth URL, exchanging the code, optional PKCE).
13
+ * Concrete providers (Google, GitHub, ...) only declare their
14
+ * endpoints, default scopes and how to map the raw profile response.
15
+ */
16
+ export declare abstract class AbstractProvider implements OAuthProviderContract {
17
+ protected readonly config: ProviderConfig;
18
+ protected readonly http: HttpClientContract;
19
+ protected readonly stateStore: StateStoreContract;
20
+ abstract readonly name: string;
21
+ protected abstract readonly authorizeUrl: string;
22
+ protected abstract readonly tokenUrl: string;
23
+ protected abstract readonly userUrl: string;
24
+ protected abstract readonly defaultScopes: string[];
25
+ /** Space, comma, or provider-specific scope separator. */
26
+ protected readonly scopeSeparator: string;
27
+ /** Set true for providers that require/accept PKCE (e.g. Twitter/X). */
28
+ protected readonly usesPKCE: boolean;
29
+ constructor(config: ProviderConfig, http: HttpClientContract, stateStore: StateStoreContract);
30
+ getAuthorizationUrl(state: string): string;
31
+ getAccessToken(code: string, state?: string): Promise<AccessTokenResult>;
32
+ getUserByToken(accessToken: string): Promise<Record<string, unknown>>;
33
+ user(code: string, state?: string): Promise<SocialUser>;
34
+ abstract mapToSocialUser(raw: Record<string, unknown>, token: AccessTokenResult): SocialUser;
35
+ /** Hook for providers needing non-default token request headers (e.g. Accept: application/json). */
36
+ protected tokenRequestHeaders(): Record<string, string>;
37
+ protected generateCodeVerifier(): string;
38
+ protected deriveCodeChallenge(verifier: string): string;
39
+ }
@@ -0,0 +1,98 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.AbstractProvider = void 0;
7
+ const node_crypto_1 = __importDefault(require("node:crypto"));
8
+ const AccessTokenResult_1 = require("../../domain/value-objects/AccessTokenResult");
9
+ const SocialiteError_1 = require("../../domain/errors/SocialiteError");
10
+ /**
11
+ * Infrastructure: AbstractProvider
12
+ *
13
+ * Template-method base class implementing the parts of the OAuth2
14
+ * "authorization code" grant that are identical across providers
15
+ * (building the auth URL, exchanging the code, optional PKCE).
16
+ * Concrete providers (Google, GitHub, ...) only declare their
17
+ * endpoints, default scopes and how to map the raw profile response.
18
+ */
19
+ class AbstractProvider {
20
+ constructor(config, http, stateStore) {
21
+ this.config = config;
22
+ this.http = http;
23
+ this.stateStore = stateStore;
24
+ /** Space, comma, or provider-specific scope separator. */
25
+ this.scopeSeparator = " ";
26
+ /** Set true for providers that require/accept PKCE (e.g. Twitter/X). */
27
+ this.usesPKCE = false;
28
+ }
29
+ getAuthorizationUrl(state) {
30
+ const scopes = (this.config.scopes ?? this.defaultScopes).join(this.scopeSeparator);
31
+ const params = new URLSearchParams({
32
+ client_id: this.config.clientId,
33
+ redirect_uri: this.config.redirectUri,
34
+ response_type: "code",
35
+ scope: scopes,
36
+ state,
37
+ ...this.config.authorizationParams,
38
+ });
39
+ if (this.usesPKCE) {
40
+ const codeVerifier = this.generateCodeVerifier();
41
+ const codeChallenge = this.deriveCodeChallenge(codeVerifier);
42
+ this.stateStore.put(state, codeVerifier);
43
+ params.set("code_challenge", codeChallenge);
44
+ params.set("code_challenge_method", "S256");
45
+ }
46
+ else {
47
+ this.stateStore.put(state, null);
48
+ }
49
+ return `${this.authorizeUrl}?${params.toString()}`;
50
+ }
51
+ async getAccessToken(code, state) {
52
+ const codeVerifier = state ? await this.stateStore.pull(state) : null;
53
+ const form = {
54
+ client_id: this.config.clientId,
55
+ client_secret: this.config.clientSecret,
56
+ redirect_uri: this.config.redirectUri,
57
+ grant_type: "authorization_code",
58
+ code,
59
+ };
60
+ if (codeVerifier) {
61
+ form.code_verifier = codeVerifier;
62
+ }
63
+ try {
64
+ const raw = await this.http.postForm(this.tokenUrl, form, this.tokenRequestHeaders());
65
+ return AccessTokenResult_1.AccessTokenResult.fromRaw(raw);
66
+ }
67
+ catch (err) {
68
+ throw new SocialiteError_1.TokenExchangeError(this.name, err.message);
69
+ }
70
+ }
71
+ async getUserByToken(accessToken) {
72
+ try {
73
+ return await this.http.getJson(this.userUrl, {
74
+ Authorization: `Bearer ${accessToken}`,
75
+ });
76
+ }
77
+ catch (err) {
78
+ throw new SocialiteError_1.UserFetchError(this.name, err.message);
79
+ }
80
+ }
81
+ async user(code, state) {
82
+ const token = await this.getAccessToken(code, state);
83
+ const raw = await this.getUserByToken(token.accessToken);
84
+ return this.mapToSocialUser(raw, token);
85
+ }
86
+ /** Hook for providers needing non-default token request headers (e.g. Accept: application/json). */
87
+ tokenRequestHeaders() {
88
+ return { Accept: "application/json" };
89
+ }
90
+ generateCodeVerifier() {
91
+ return node_crypto_1.default.randomBytes(32).toString("base64url");
92
+ }
93
+ deriveCodeChallenge(verifier) {
94
+ return node_crypto_1.default.createHash("sha256").update(verifier).digest("base64url");
95
+ }
96
+ }
97
+ exports.AbstractProvider = AbstractProvider;
98
+ //# sourceMappingURL=AbstractProvider.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"AbstractProvider.js","sourceRoot":"","sources":["../../../src/infrastructure/providers/AbstractProvider.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,14 @@
1
+ import { AbstractProvider } from "./AbstractProvider";
2
+ import { SocialUser } from "../../domain/entities/SocialUser";
3
+ import { AccessTokenResult } from "../../domain/value-objects/AccessTokenResult";
4
+ export declare class FacebookProvider extends AbstractProvider {
5
+ readonly name = "facebook";
6
+ protected readonly authorizeUrl = "https://www.facebook.com/v19.0/dialog/oauth";
7
+ protected readonly tokenUrl = "https://graph.facebook.com/v19.0/oauth/access_token";
8
+ protected readonly userUrl = "https://graph.facebook.com/v19.0/me";
9
+ protected readonly defaultScopes: string[];
10
+ protected readonly scopeSeparator = ",";
11
+ getAccessToken(code: string): Promise<AccessTokenResult>;
12
+ getUserByToken(accessToken: string): Promise<Record<string, unknown>>;
13
+ mapToSocialUser(raw: Record<string, unknown>, token: AccessTokenResult): SocialUser;
14
+ }
@@ -0,0 +1,55 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.FacebookProvider = void 0;
4
+ const AbstractProvider_1 = require("./AbstractProvider");
5
+ const SocialUser_1 = require("../../domain/entities/SocialUser");
6
+ const AccessTokenResult_1 = require("../../domain/value-objects/AccessTokenResult");
7
+ const GRAPH_VERSION = "v19.0";
8
+ class FacebookProvider extends AbstractProvider_1.AbstractProvider {
9
+ constructor() {
10
+ super(...arguments);
11
+ this.name = "facebook";
12
+ this.authorizeUrl = `https://www.facebook.com/${GRAPH_VERSION}/dialog/oauth`;
13
+ this.tokenUrl = `https://graph.facebook.com/${GRAPH_VERSION}/oauth/access_token`;
14
+ this.userUrl = `https://graph.facebook.com/${GRAPH_VERSION}/me`;
15
+ this.defaultScopes = ["email", "public_profile"];
16
+ this.scopeSeparator = ",";
17
+ }
18
+ // Facebook's Graph API expects the token exchange as a GET request with
19
+ // query parameters rather than a POST form body, so we override the
20
+ // template method's default behaviour here.
21
+ async getAccessToken(code) {
22
+ const params = new URLSearchParams({
23
+ client_id: this.config.clientId,
24
+ client_secret: this.config.clientSecret,
25
+ redirect_uri: this.config.redirectUri,
26
+ code,
27
+ });
28
+ const raw = await this.http.getJson(`${this.tokenUrl}?${params.toString()}`);
29
+ return AccessTokenResult_1.AccessTokenResult.fromRaw(raw);
30
+ }
31
+ async getUserByToken(accessToken) {
32
+ const params = new URLSearchParams({
33
+ fields: "id,name,email,picture.type(large)",
34
+ access_token: accessToken,
35
+ });
36
+ return this.http.getJson(`${this.userUrl}?${params.toString()}`);
37
+ }
38
+ mapToSocialUser(raw, token) {
39
+ const picture = raw.picture;
40
+ return new SocialUser_1.SocialUser({
41
+ id: String(raw.id),
42
+ nickname: null,
43
+ name: raw.name ?? null,
44
+ email: raw.email ?? null,
45
+ avatar: picture?.data?.url ?? null,
46
+ provider: this.name,
47
+ accessToken: token.accessToken,
48
+ refreshToken: token.refreshToken,
49
+ expiresIn: token.expiresIn,
50
+ raw,
51
+ });
52
+ }
53
+ }
54
+ exports.FacebookProvider = FacebookProvider;
55
+ //# sourceMappingURL=FacebookProvider.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"FacebookProvider.js","sourceRoot":"","sources":["../../../src/infrastructure/providers/FacebookProvider.ts"],"names":[],"mappings":";;;AAAA,yDAAsD;AACtD,iEAA8D;AAC9D,oFAAiF;AAEjF,MAAM,aAAa,GAAG,OAAO,CAAC;AAE9B,MAAa,gBAAiB,SAAQ,mCAAgB;IAAtD;;QACW,SAAI,GAAG,UAAU,CAAC;QACR,iBAAY,GAAG,4BAA4B,aAAa,eAAe,CAAC;QACxE,aAAQ,GAAG,8BAA8B,aAAa,qBAAqB,CAAC;QAC5E,YAAO,GAAG,8BAA8B,aAAa,KAAK,CAAC;QAC3D,kBAAa,GAAG,CAAC,OAAO,EAAE,gBAAgB,CAAC,CAAC;QAC5C,mBAAc,GAAG,GAAG,CAAC;IAuC1C,CAAC;IArCC,wEAAwE;IACxE,oEAAoE;IACpE,4CAA4C;IAC5C,KAAK,CAAC,cAAc,CAAC,IAAY;QAC/B,MAAM,MAAM,GAAG,IAAI,eAAe,CAAC;YACjC,SAAS,EAAE,IAAI,CAAC,MAAM,CAAC,QAAQ;YAC/B,aAAa,EAAE,IAAI,CAAC,MAAM,CAAC,YAAY;YACvC,YAAY,EAAE,IAAI,CAAC,MAAM,CAAC,WAAW;YACrC,IAAI;SACL,CAAC,CAAC;QACH,MAAM,GAAG,GAAG,MAAM,IAAI,CAAC,IAAI,CAAC,OAAO,CAA0B,GAAG,IAAI,CAAC,QAAQ,IAAI,MAAM,CAAC,QAAQ,EAAE,EAAE,CAAC,CAAC;QACtG,OAAO,qCAAiB,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC;IACxC,CAAC;IAED,KAAK,CAAC,cAAc,CAAC,WAAmB;QACtC,MAAM,MAAM,GAAG,IAAI,eAAe,CAAC;YACjC,MAAM,EAAE,mCAAmC;YAC3C,YAAY,EAAE,WAAW;SAC1B,CAAC,CAAC;QACH,OAAO,IAAI,CAAC,IAAI,CAAC,OAAO,CAA0B,GAAG,IAAI,CAAC,OAAO,IAAI,MAAM,CAAC,QAAQ,EAAE,EAAE,CAAC,CAAC;IAC5F,CAAC;IAED,eAAe,CAAC,GAA4B,EAAE,KAAwB;QACpE,MAAM,OAAO,GAAG,GAAG,CAAC,OAAkD,CAAC;QACvE,OAAO,IAAI,uBAAU,CAAC;YACpB,EAAE,EAAE,MAAM,CAAC,GAAG,CAAC,EAAE,CAAC;YAClB,QAAQ,EAAE,IAAI;YACd,IAAI,EAAG,GAAG,CAAC,IAAe,IAAI,IAAI;YAClC,KAAK,EAAG,GAAG,CAAC,KAAgB,IAAI,IAAI;YACpC,MAAM,EAAE,OAAO,EAAE,IAAI,EAAE,GAAG,IAAI,IAAI;YAClC,QAAQ,EAAE,IAAI,CAAC,IAAI;YACnB,WAAW,EAAE,KAAK,CAAC,WAAW;YAC9B,YAAY,EAAE,KAAK,CAAC,YAAY;YAChC,SAAS,EAAE,KAAK,CAAC,SAAS;YAC1B,GAAG;SACJ,CAAC,CAAC;IACL,CAAC;CACF;AA7CD,4CA6CC"}
@@ -0,0 +1,12 @@
1
+ import { AbstractProvider } from "./AbstractProvider";
2
+ import { SocialUser } from "../../domain/entities/SocialUser";
3
+ import { AccessTokenResult } from "../../domain/value-objects/AccessTokenResult";
4
+ export declare class GithubProvider extends AbstractProvider {
5
+ readonly name = "github";
6
+ protected readonly authorizeUrl = "https://github.com/login/oauth/authorize";
7
+ protected readonly tokenUrl = "https://github.com/login/oauth/access_token";
8
+ protected readonly userUrl = "https://api.github.com/user";
9
+ protected readonly defaultScopes: string[];
10
+ getUserByToken(accessToken: string): Promise<Record<string, unknown>>;
11
+ mapToSocialUser(raw: Record<string, unknown>, token: AccessTokenResult): SocialUser;
12
+ }
@@ -0,0 +1,55 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.GithubProvider = void 0;
4
+ const AbstractProvider_1 = require("./AbstractProvider");
5
+ const SocialUser_1 = require("../../domain/entities/SocialUser");
6
+ const SocialiteError_1 = require("../../domain/errors/SocialiteError");
7
+ class GithubProvider extends AbstractProvider_1.AbstractProvider {
8
+ constructor() {
9
+ super(...arguments);
10
+ this.name = "github";
11
+ this.authorizeUrl = "https://github.com/login/oauth/authorize";
12
+ this.tokenUrl = "https://github.com/login/oauth/access_token";
13
+ this.userUrl = "https://api.github.com/user";
14
+ this.defaultScopes = ["read:user", "user:email"];
15
+ }
16
+ // GitHub's API requires a User-Agent header, which our generic
17
+ // AbstractProvider.getUserByToken doesn't send.
18
+ async getUserByToken(accessToken) {
19
+ try {
20
+ const user = await this.http.getJson(this.userUrl, {
21
+ Authorization: `Bearer ${accessToken}`,
22
+ "User-Agent": "socialite-sdk",
23
+ });
24
+ // GitHub only returns a public email by default; if it's null,
25
+ // fall back to the dedicated emails endpoint for the primary one.
26
+ if (!user.email) {
27
+ const emails = await this.http.getJson("https://api.github.com/user/emails", { Authorization: `Bearer ${accessToken}`, "User-Agent": "socialite-sdk" });
28
+ const primary = emails.find((e) => e.primary && e.verified) ?? emails[0];
29
+ if (primary) {
30
+ user.email = primary.email;
31
+ }
32
+ }
33
+ return user;
34
+ }
35
+ catch (err) {
36
+ throw new SocialiteError_1.UserFetchError(this.name, err.message);
37
+ }
38
+ }
39
+ mapToSocialUser(raw, token) {
40
+ return new SocialUser_1.SocialUser({
41
+ id: String(raw.id),
42
+ nickname: raw.login ?? null,
43
+ name: raw.name ?? null,
44
+ email: raw.email ?? null,
45
+ avatar: raw.avatar_url ?? null,
46
+ provider: this.name,
47
+ accessToken: token.accessToken,
48
+ refreshToken: token.refreshToken,
49
+ expiresIn: token.expiresIn,
50
+ raw,
51
+ });
52
+ }
53
+ }
54
+ exports.GithubProvider = GithubProvider;
55
+ //# sourceMappingURL=GithubProvider.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"GithubProvider.js","sourceRoot":"","sources":["../../../src/infrastructure/providers/GithubProvider.ts"],"names":[],"mappings":";;;AAAA,yDAAsD;AACtD,iEAA8D;AAE9D,uEAAoE;AAEpE,MAAa,cAAe,SAAQ,mCAAgB;IAApD;;QACW,SAAI,GAAG,QAAQ,CAAC;QACN,iBAAY,GAAG,0CAA0C,CAAC;QAC1D,aAAQ,GAAG,6CAA6C,CAAC;QACzD,YAAO,GAAG,6BAA6B,CAAC;QACxC,kBAAa,GAAG,CAAC,WAAW,EAAE,YAAY,CAAC,CAAC;IA4CjE,CAAC;IA1CC,+DAA+D;IAC/D,gDAAgD;IAChD,KAAK,CAAC,cAAc,CAAC,WAAmB;QACtC,IAAI,CAAC;YACH,MAAM,IAAI,GAAG,MAAM,IAAI,CAAC,IAAI,CAAC,OAAO,CAA0B,IAAI,CAAC,OAAO,EAAE;gBAC1E,aAAa,EAAE,UAAU,WAAW,EAAE;gBACtC,YAAY,EAAE,eAAe;aAC9B,CAAC,CAAC;YAEH,+DAA+D;YAC/D,kEAAkE;YAClE,IAAI,CAAC,IAAI,CAAC,KAAK,EAAE,CAAC;gBAChB,MAAM,MAAM,GAAG,MAAM,IAAI,CAAC,IAAI,CAAC,OAAO,CACpC,oCAAoC,EACpC,EAAE,aAAa,EAAE,UAAU,WAAW,EAAE,EAAE,YAAY,EAAE,eAAe,EAAE,CAC1E,CAAC;gBACF,MAAM,OAAO,GAAG,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,OAAO,IAAI,CAAC,CAAC,QAAQ,CAAC,IAAI,MAAM,CAAC,CAAC,CAAC,CAAC;gBACzE,IAAI,OAAO,EAAE,CAAC;oBACZ,IAAI,CAAC,KAAK,GAAG,OAAO,CAAC,KAAK,CAAC;gBAC7B,CAAC;YACH,CAAC;YAED,OAAO,IAAI,CAAC;QACd,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACb,MAAM,IAAI,+BAAc,CAAC,IAAI,CAAC,IAAI,EAAG,GAAa,CAAC,OAAO,CAAC,CAAC;QAC9D,CAAC;IACH,CAAC;IAED,eAAe,CAAC,GAA4B,EAAE,KAAwB;QACpE,OAAO,IAAI,uBAAU,CAAC;YACpB,EAAE,EAAE,MAAM,CAAC,GAAG,CAAC,EAAE,CAAC;YAClB,QAAQ,EAAG,GAAG,CAAC,KAAgB,IAAI,IAAI;YACvC,IAAI,EAAG,GAAG,CAAC,IAAe,IAAI,IAAI;YAClC,KAAK,EAAG,GAAG,CAAC,KAAgB,IAAI,IAAI;YACpC,MAAM,EAAG,GAAG,CAAC,UAAqB,IAAI,IAAI;YAC1C,QAAQ,EAAE,IAAI,CAAC,IAAI;YACnB,WAAW,EAAE,KAAK,CAAC,WAAW;YAC9B,YAAY,EAAE,KAAK,CAAC,YAAY;YAChC,SAAS,EAAE,KAAK,CAAC,SAAS;YAC1B,GAAG;SACJ,CAAC,CAAC;IACL,CAAC;CACF;AAjDD,wCAiDC"}
@@ -0,0 +1,11 @@
1
+ import { AbstractProvider } from "./AbstractProvider";
2
+ import { SocialUser } from "../../domain/entities/SocialUser";
3
+ import { AccessTokenResult } from "../../domain/value-objects/AccessTokenResult";
4
+ export declare class GoogleProvider extends AbstractProvider {
5
+ readonly name = "google";
6
+ protected readonly authorizeUrl = "https://accounts.google.com/o/oauth2/v2/auth";
7
+ protected readonly tokenUrl = "https://oauth2.googleapis.com/token";
8
+ protected readonly userUrl = "https://www.googleapis.com/oauth2/v3/userinfo";
9
+ protected readonly defaultScopes: string[];
10
+ mapToSocialUser(raw: Record<string, unknown>, token: AccessTokenResult): SocialUser;
11
+ }
@@ -0,0 +1,31 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.GoogleProvider = void 0;
4
+ const AbstractProvider_1 = require("./AbstractProvider");
5
+ const SocialUser_1 = require("../../domain/entities/SocialUser");
6
+ class GoogleProvider extends AbstractProvider_1.AbstractProvider {
7
+ constructor() {
8
+ super(...arguments);
9
+ this.name = "google";
10
+ this.authorizeUrl = "https://accounts.google.com/o/oauth2/v2/auth";
11
+ this.tokenUrl = "https://oauth2.googleapis.com/token";
12
+ this.userUrl = "https://www.googleapis.com/oauth2/v3/userinfo";
13
+ this.defaultScopes = ["openid", "profile", "email"];
14
+ }
15
+ mapToSocialUser(raw, token) {
16
+ return new SocialUser_1.SocialUser({
17
+ id: String(raw.sub),
18
+ nickname: null,
19
+ name: raw.name ?? null,
20
+ email: raw.email ?? null,
21
+ avatar: raw.picture ?? null,
22
+ provider: this.name,
23
+ accessToken: token.accessToken,
24
+ refreshToken: token.refreshToken,
25
+ expiresIn: token.expiresIn,
26
+ raw,
27
+ });
28
+ }
29
+ }
30
+ exports.GoogleProvider = GoogleProvider;
31
+ //# sourceMappingURL=GoogleProvider.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"GoogleProvider.js","sourceRoot":"","sources":["../../../src/infrastructure/providers/GoogleProvider.ts"],"names":[],"mappings":";;;AAAA,yDAAsD;AACtD,iEAA8D;AAG9D,MAAa,cAAe,SAAQ,mCAAgB;IAApD;;QACW,SAAI,GAAG,QAAQ,CAAC;QACN,iBAAY,GAAG,8CAA8C,CAAC;QAC9D,aAAQ,GAAG,qCAAqC,CAAC;QACjD,YAAO,GAAG,+CAA+C,CAAC;QAC1D,kBAAa,GAAG,CAAC,QAAQ,EAAE,SAAS,EAAE,OAAO,CAAC,CAAC;IAgBpE,CAAC;IAdC,eAAe,CAAC,GAA4B,EAAE,KAAwB;QACpE,OAAO,IAAI,uBAAU,CAAC;YACpB,EAAE,EAAE,MAAM,CAAC,GAAG,CAAC,GAAG,CAAC;YACnB,QAAQ,EAAE,IAAI;YACd,IAAI,EAAG,GAAG,CAAC,IAAe,IAAI,IAAI;YAClC,KAAK,EAAG,GAAG,CAAC,KAAgB,IAAI,IAAI;YACpC,MAAM,EAAG,GAAG,CAAC,OAAkB,IAAI,IAAI;YACvC,QAAQ,EAAE,IAAI,CAAC,IAAI;YACnB,WAAW,EAAE,KAAK,CAAC,WAAW;YAC9B,YAAY,EAAE,KAAK,CAAC,YAAY;YAChC,SAAS,EAAE,KAAK,CAAC,SAAS;YAC1B,GAAG;SACJ,CAAC,CAAC;IACL,CAAC;CACF;AArBD,wCAqBC"}
@@ -0,0 +1,11 @@
1
+ import { AbstractProvider } from "./AbstractProvider";
2
+ import { SocialUser } from "../../domain/entities/SocialUser";
3
+ import { AccessTokenResult } from "../../domain/value-objects/AccessTokenResult";
4
+ export declare class LinkedinProvider extends AbstractProvider {
5
+ readonly name = "linkedin";
6
+ protected readonly authorizeUrl = "https://www.linkedin.com/oauth/v2/authorization";
7
+ protected readonly tokenUrl = "https://www.linkedin.com/oauth/v2/accessToken";
8
+ protected readonly userUrl = "https://api.linkedin.com/v2/userinfo";
9
+ protected readonly defaultScopes: string[];
10
+ mapToSocialUser(raw: Record<string, unknown>, token: AccessTokenResult): SocialUser;
11
+ }
@@ -0,0 +1,33 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.LinkedinProvider = void 0;
4
+ const AbstractProvider_1 = require("./AbstractProvider");
5
+ const SocialUser_1 = require("../../domain/entities/SocialUser");
6
+ class LinkedinProvider extends AbstractProvider_1.AbstractProvider {
7
+ constructor() {
8
+ super(...arguments);
9
+ this.name = "linkedin";
10
+ this.authorizeUrl = "https://www.linkedin.com/oauth/v2/authorization";
11
+ this.tokenUrl = "https://www.linkedin.com/oauth/v2/accessToken";
12
+ // LinkedIn's current "Sign In with LinkedIn using OpenID Connect" product
13
+ // exposes profile data through the standard OIDC userinfo endpoint.
14
+ this.userUrl = "https://api.linkedin.com/v2/userinfo";
15
+ this.defaultScopes = ["openid", "profile", "email"];
16
+ }
17
+ mapToSocialUser(raw, token) {
18
+ return new SocialUser_1.SocialUser({
19
+ id: String(raw.sub),
20
+ nickname: null,
21
+ name: raw.name ?? null,
22
+ email: raw.email ?? null,
23
+ avatar: raw.picture ?? null,
24
+ provider: this.name,
25
+ accessToken: token.accessToken,
26
+ refreshToken: token.refreshToken,
27
+ expiresIn: token.expiresIn,
28
+ raw,
29
+ });
30
+ }
31
+ }
32
+ exports.LinkedinProvider = LinkedinProvider;
33
+ //# sourceMappingURL=LinkedinProvider.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"LinkedinProvider.js","sourceRoot":"","sources":["../../../src/infrastructure/providers/LinkedinProvider.ts"],"names":[],"mappings":";;;AAAA,yDAAsD;AACtD,iEAA8D;AAG9D,MAAa,gBAAiB,SAAQ,mCAAgB;IAAtD;;QACW,SAAI,GAAG,UAAU,CAAC;QACR,iBAAY,GAAG,iDAAiD,CAAC;QACjE,aAAQ,GAAG,+CAA+C,CAAC;QAC9E,0EAA0E;QAC1E,oEAAoE;QACjD,YAAO,GAAG,sCAAsC,CAAC;QACjD,kBAAa,GAAG,CAAC,QAAQ,EAAE,SAAS,EAAE,OAAO,CAAC,CAAC;IAgBpE,CAAC;IAdC,eAAe,CAAC,GAA4B,EAAE,KAAwB;QACpE,OAAO,IAAI,uBAAU,CAAC;YACpB,EAAE,EAAE,MAAM,CAAC,GAAG,CAAC,GAAG,CAAC;YACnB,QAAQ,EAAE,IAAI;YACd,IAAI,EAAG,GAAG,CAAC,IAAe,IAAI,IAAI;YAClC,KAAK,EAAG,GAAG,CAAC,KAAgB,IAAI,IAAI;YACpC,MAAM,EAAG,GAAG,CAAC,OAAkB,IAAI,IAAI;YACvC,QAAQ,EAAE,IAAI,CAAC,IAAI;YACnB,WAAW,EAAE,KAAK,CAAC,WAAW;YAC9B,YAAY,EAAE,KAAK,CAAC,YAAY;YAChC,SAAS,EAAE,KAAK,CAAC,SAAS;YAC1B,GAAG;SACJ,CAAC,CAAC;IACL,CAAC;CACF;AAvBD,4CAuBC"}
@@ -0,0 +1,11 @@
1
+ import { AbstractProvider } from "./AbstractProvider";
2
+ import { SocialUser } from "../../domain/entities/SocialUser";
3
+ import { AccessTokenResult } from "../../domain/value-objects/AccessTokenResult";
4
+ export declare class MicrosoftProvider extends AbstractProvider {
5
+ readonly name = "microsoft";
6
+ protected readonly authorizeUrl = "https://login.microsoftonline.com/common/oauth2/v2.0/authorize";
7
+ protected readonly tokenUrl = "https://login.microsoftonline.com/common/oauth2/v2.0/token";
8
+ protected readonly userUrl = "https://graph.microsoft.com/v1.0/me";
9
+ protected readonly defaultScopes: string[];
10
+ mapToSocialUser(raw: Record<string, unknown>, token: AccessTokenResult): SocialUser;
11
+ }