@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.
- package/README.md +133 -0
- package/dist/application/dto/ProviderConfig.d.ts +23 -0
- package/dist/application/dto/ProviderConfig.js +3 -0
- package/dist/application/dto/ProviderConfig.js.map +1 -0
- package/dist/application/services/SocialiteManager.d.ts +50 -0
- package/dist/application/services/SocialiteManager.js +73 -0
- package/dist/application/services/SocialiteManager.js.map +1 -0
- package/dist/domain/contracts/HttpClientContract.d.ts +12 -0
- package/dist/domain/contracts/HttpClientContract.js +3 -0
- package/dist/domain/contracts/HttpClientContract.js.map +1 -0
- package/dist/domain/contracts/OAuthProviderContract.d.ts +28 -0
- package/dist/domain/contracts/OAuthProviderContract.js +3 -0
- package/dist/domain/contracts/OAuthProviderContract.js.map +1 -0
- package/dist/domain/contracts/StateStoreContract.d.ts +13 -0
- package/dist/domain/contracts/StateStoreContract.js +3 -0
- package/dist/domain/contracts/StateStoreContract.js.map +1 -0
- package/dist/domain/entities/SocialUser.d.ts +36 -0
- package/dist/domain/entities/SocialUser.js +33 -0
- package/dist/domain/entities/SocialUser.js.map +1 -0
- package/dist/domain/errors/SocialiteError.d.ts +18 -0
- package/dist/domain/errors/SocialiteError.js +46 -0
- package/dist/domain/errors/SocialiteError.js.map +1 -0
- package/dist/domain/value-objects/AccessTokenResult.d.ts +16 -0
- package/dist/domain/value-objects/AccessTokenResult.js +28 -0
- package/dist/domain/value-objects/AccessTokenResult.js.map +1 -0
- package/dist/domain/value-objects/ProviderName.d.ts +9 -0
- package/dist/domain/value-objects/ProviderName.js +22 -0
- package/dist/domain/value-objects/ProviderName.js.map +1 -0
- package/dist/index.d.ts +36 -0
- package/dist/index.js +56 -0
- package/dist/index.js.map +1 -0
- package/dist/infrastructure/http/FetchHttpClient.d.ts +13 -0
- package/dist/infrastructure/http/FetchHttpClient.js +58 -0
- package/dist/infrastructure/http/FetchHttpClient.js.map +1 -0
- package/dist/infrastructure/http/MemoryStateStore.d.ts +15 -0
- package/dist/infrastructure/http/MemoryStateStore.js +29 -0
- package/dist/infrastructure/http/MemoryStateStore.js.map +1 -0
- package/dist/infrastructure/providers/AbstractProvider.d.ts +39 -0
- package/dist/infrastructure/providers/AbstractProvider.js +98 -0
- package/dist/infrastructure/providers/AbstractProvider.js.map +1 -0
- package/dist/infrastructure/providers/FacebookProvider.d.ts +14 -0
- package/dist/infrastructure/providers/FacebookProvider.js +55 -0
- package/dist/infrastructure/providers/FacebookProvider.js.map +1 -0
- package/dist/infrastructure/providers/GithubProvider.d.ts +12 -0
- package/dist/infrastructure/providers/GithubProvider.js +55 -0
- package/dist/infrastructure/providers/GithubProvider.js.map +1 -0
- package/dist/infrastructure/providers/GoogleProvider.d.ts +11 -0
- package/dist/infrastructure/providers/GoogleProvider.js +31 -0
- package/dist/infrastructure/providers/GoogleProvider.js.map +1 -0
- package/dist/infrastructure/providers/LinkedinProvider.d.ts +11 -0
- package/dist/infrastructure/providers/LinkedinProvider.js +33 -0
- package/dist/infrastructure/providers/LinkedinProvider.js.map +1 -0
- package/dist/infrastructure/providers/MicrosoftProvider.d.ts +11 -0
- package/dist/infrastructure/providers/MicrosoftProvider.js +32 -0
- package/dist/infrastructure/providers/MicrosoftProvider.js.map +1 -0
- package/dist/infrastructure/providers/ProviderFactory.d.ts +15 -0
- package/dist/infrastructure/providers/ProviderFactory.js +36 -0
- package/dist/infrastructure/providers/ProviderFactory.js.map +1 -0
- package/dist/infrastructure/providers/TwitterProvider.d.ts +13 -0
- package/dist/infrastructure/providers/TwitterProvider.js +43 -0
- package/dist/infrastructure/providers/TwitterProvider.js.map +1 -0
- package/package.json +47 -0
package/README.md
ADDED
|
@@ -0,0 +1,133 @@
|
|
|
1
|
+
# socialite
|
|
2
|
+
|
|
3
|
+
A Node.js / TypeScript SDK for "Login with ..." (OAuth2) flows, built with
|
|
4
|
+
Domain-Driven Design layering. Supports:
|
|
5
|
+
|
|
6
|
+
- Google
|
|
7
|
+
- Microsoft (Azure AD / personal accounts)
|
|
8
|
+
- Facebook
|
|
9
|
+
- GitHub
|
|
10
|
+
- Twitter / X (OAuth 2.0 + PKCE)
|
|
11
|
+
- LinkedIn (OpenID Connect)
|
|
12
|
+
|
|
13
|
+
## Why DDD here?
|
|
14
|
+
|
|
15
|
+
Each provider is a slightly different dialect of OAuth2 (different token
|
|
16
|
+
endpoints, some need PKCE, some need GET instead of POST for the token
|
|
17
|
+
exchange, etc). Structuring the SDK in layers keeps that variance contained:
|
|
18
|
+
|
|
19
|
+
```
|
|
20
|
+
src/
|
|
21
|
+
domain/ <- Pure business rules & contracts (ports). Zero HTTP, zero I/O.
|
|
22
|
+
entities/ SocialUser
|
|
23
|
+
value-objects/ AccessTokenResult, ProviderName
|
|
24
|
+
contracts/ OAuthProviderContract, HttpClientContract, StateStoreContract
|
|
25
|
+
errors/ SocialiteError and subclasses
|
|
26
|
+
|
|
27
|
+
application/ <- Orchestrates domain contracts for the outside world.
|
|
28
|
+
services/ SocialiteManager (the public facade / use-case layer)
|
|
29
|
+
dto/ ProviderConfig, SocialiteConfig
|
|
30
|
+
|
|
31
|
+
infrastructure/ <- Concrete adapters implementing the domain contracts.
|
|
32
|
+
http/ FetchHttpClient, MemoryStateStore
|
|
33
|
+
providers/ AbstractProvider + one class per provider + ProviderFactory
|
|
34
|
+
|
|
35
|
+
index.ts <- Public entry point (Socialite.create(...))
|
|
36
|
+
```
|
|
37
|
+
|
|
38
|
+
The **application layer only depends on domain contracts**, never on a
|
|
39
|
+
concrete provider class. That means adding a 7th provider (say, Apple) is a
|
|
40
|
+
matter of adding one infrastructure class + one registry entry -- nothing
|
|
41
|
+
in `SocialiteManager` changes (Open/Closed Principle).
|
|
42
|
+
|
|
43
|
+
## Install
|
|
44
|
+
|
|
45
|
+
```bash
|
|
46
|
+
npm install socialite
|
|
47
|
+
```
|
|
48
|
+
|
|
49
|
+
## Usage
|
|
50
|
+
|
|
51
|
+
```ts
|
|
52
|
+
import { Socialite } from "@bactv/socialite";
|
|
53
|
+
|
|
54
|
+
const socialite = Socialite.create({
|
|
55
|
+
google: {
|
|
56
|
+
clientId: process.env.GOOGLE_CLIENT_ID!,
|
|
57
|
+
clientSecret: process.env.GOOGLE_CLIENT_SECRET!,
|
|
58
|
+
redirectUri: "https://myapp.com/auth/google/callback",
|
|
59
|
+
},
|
|
60
|
+
github: {
|
|
61
|
+
clientId: process.env.GITHUB_CLIENT_ID!,
|
|
62
|
+
clientSecret: process.env.GITHUB_CLIENT_SECRET!,
|
|
63
|
+
redirectUri: "https://myapp.com/auth/github/callback",
|
|
64
|
+
},
|
|
65
|
+
// ...microsoft, facebook, twitter, linkedin follow the same shape
|
|
66
|
+
});
|
|
67
|
+
|
|
68
|
+
// 1) Send the user to the provider's consent screen.
|
|
69
|
+
app.get("/auth/:provider", (req, res) => {
|
|
70
|
+
const { url, state } = socialite.driver(req.params.provider).redirect();
|
|
71
|
+
res.cookie("oauth_state", state, { httpOnly: true });
|
|
72
|
+
res.redirect(url);
|
|
73
|
+
});
|
|
74
|
+
|
|
75
|
+
// 2) Handle the redirect back from the provider.
|
|
76
|
+
app.get("/auth/:provider/callback", async (req, res) => {
|
|
77
|
+
const { code, state } = req.query;
|
|
78
|
+
if (state !== req.cookies.oauth_state) {
|
|
79
|
+
return res.status(400).send("Invalid state");
|
|
80
|
+
}
|
|
81
|
+
const user = await socialite.driver(req.params.provider).callback(code, state);
|
|
82
|
+
// user.id, user.name, user.email, user.avatar, user.accessToken, ...
|
|
83
|
+
res.json(user.toJSON());
|
|
84
|
+
});
|
|
85
|
+
```
|
|
86
|
+
|
|
87
|
+
See `examples/express-example.ts` for a full working route setup across all
|
|
88
|
+
six providers.
|
|
89
|
+
|
|
90
|
+
## Custom scopes / extra params
|
|
91
|
+
|
|
92
|
+
```ts
|
|
93
|
+
Socialite.create({
|
|
94
|
+
google: {
|
|
95
|
+
clientId: "...",
|
|
96
|
+
clientSecret: "...",
|
|
97
|
+
redirectUri: "...",
|
|
98
|
+
scopes: ["openid", "email", "profile", "https://www.googleapis.com/auth/calendar.readonly"],
|
|
99
|
+
authorizationParams: { access_type: "offline", prompt: "consent" },
|
|
100
|
+
},
|
|
101
|
+
});
|
|
102
|
+
```
|
|
103
|
+
|
|
104
|
+
## Swapping infrastructure
|
|
105
|
+
|
|
106
|
+
Both the HTTP client and the CSRF/PKCE state store are injected via
|
|
107
|
+
constructor and implement plain interfaces (`HttpClientContract`,
|
|
108
|
+
`StateStoreContract`), so you can supply your own -- e.g. a Redis-backed
|
|
109
|
+
state store for a multi-instance deployment:
|
|
110
|
+
|
|
111
|
+
```ts
|
|
112
|
+
import { Socialite, StateStoreContract } from "socialite";
|
|
113
|
+
|
|
114
|
+
class RedisStateStore implements StateStoreContract {
|
|
115
|
+
async put(state: string, codeVerifier: string | null) { /* ... */ }
|
|
116
|
+
async pull(state: string) { /* ... */ return null; }
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
const socialite = Socialite.create(config, undefined, new RedisStateStore());
|
|
120
|
+
```
|
|
121
|
+
|
|
122
|
+
## Error handling
|
|
123
|
+
|
|
124
|
+
All failure modes raise a subclass of `SocialiteError`:
|
|
125
|
+
`ProviderNotConfiguredError`, `UnsupportedProviderError`,
|
|
126
|
+
`TokenExchangeError`, `UserFetchError`, `InvalidStateError`.
|
|
127
|
+
|
|
128
|
+
## Build
|
|
129
|
+
|
|
130
|
+
```bash
|
|
131
|
+
npm install
|
|
132
|
+
npm run build
|
|
133
|
+
```
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Application DTO: ProviderConfig
|
|
3
|
+
*
|
|
4
|
+
* Plain data shape supplied by the consumer of the SDK (credentials
|
|
5
|
+
* obtained from each provider's developer console).
|
|
6
|
+
*/
|
|
7
|
+
export interface ProviderConfig {
|
|
8
|
+
clientId: string;
|
|
9
|
+
clientSecret: string;
|
|
10
|
+
redirectUri: string;
|
|
11
|
+
/** Override default scopes if needed. */
|
|
12
|
+
scopes?: string[];
|
|
13
|
+
/** Extra query params to merge into the authorization URL. */
|
|
14
|
+
authorizationParams?: Record<string, string>;
|
|
15
|
+
}
|
|
16
|
+
export interface SocialiteConfig {
|
|
17
|
+
google?: ProviderConfig;
|
|
18
|
+
microsoft?: ProviderConfig;
|
|
19
|
+
facebook?: ProviderConfig;
|
|
20
|
+
github?: ProviderConfig;
|
|
21
|
+
twitter?: ProviderConfig;
|
|
22
|
+
linkedin?: ProviderConfig;
|
|
23
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ProviderConfig.js","sourceRoot":"","sources":["../../../src/application/dto/ProviderConfig.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
import { SocialiteConfig } from "../dto/ProviderConfig";
|
|
2
|
+
import { OAuthProviderContract } from "../../domain/contracts/OAuthProviderContract";
|
|
3
|
+
import { HttpClientContract } from "../../domain/contracts/HttpClientContract";
|
|
4
|
+
import { StateStoreContract } from "../../domain/contracts/StateStoreContract";
|
|
5
|
+
import { ProviderName } from "../../domain/value-objects/ProviderName";
|
|
6
|
+
import { SocialUser } from "../../domain/entities/SocialUser";
|
|
7
|
+
export interface RedirectResult {
|
|
8
|
+
/** URL to send the end-user's browser to. */
|
|
9
|
+
url: string;
|
|
10
|
+
/** Opaque CSRF token; persist it (cookie/session) and pass back into `.callback()`. */
|
|
11
|
+
state: string;
|
|
12
|
+
}
|
|
13
|
+
/**
|
|
14
|
+
* Application Service: SocialiteManager
|
|
15
|
+
*
|
|
16
|
+
* The public facade of the SDK. It orchestrates domain contracts and
|
|
17
|
+
* infrastructure adapters but contains no provider-specific HTTP logic
|
|
18
|
+
* itself -- that all lives behind OAuthProviderContract implementations.
|
|
19
|
+
*
|
|
20
|
+
* Usage:
|
|
21
|
+
* const socialite = Socialite.create({ google: {...}, github: {...} });
|
|
22
|
+
* const { url, state } = socialite.driver("google").redirect();
|
|
23
|
+
* // ...later, in your OAuth callback route:
|
|
24
|
+
* const user = await socialite.driver("google").callback(code, state);
|
|
25
|
+
*/
|
|
26
|
+
export declare class SocialiteManager {
|
|
27
|
+
private readonly config;
|
|
28
|
+
private readonly http;
|
|
29
|
+
private readonly stateStore;
|
|
30
|
+
private readonly cache;
|
|
31
|
+
constructor(config: SocialiteConfig, http?: HttpClientContract, stateStore?: StateStoreContract);
|
|
32
|
+
/** Resolve (and memoize) the provider identified by `name`. */
|
|
33
|
+
driver(name: string): ProviderFacade;
|
|
34
|
+
/** List provider names currently configured with credentials. */
|
|
35
|
+
configuredProviders(): ProviderName[];
|
|
36
|
+
}
|
|
37
|
+
/**
|
|
38
|
+
* Thin per-request facade returned by `driver()`, giving callers a small,
|
|
39
|
+
* readable API surface (`redirect()` / `callback()`) instead of exposing
|
|
40
|
+
* the full OAuthProviderContract.
|
|
41
|
+
*/
|
|
42
|
+
declare class ProviderFacade {
|
|
43
|
+
private readonly provider;
|
|
44
|
+
constructor(provider: OAuthProviderContract);
|
|
45
|
+
/** Step 1: build the URL to redirect the user to, plus a state token to persist. */
|
|
46
|
+
redirect(): RedirectResult;
|
|
47
|
+
/** Step 2: exchange the callback's `code` (+ the `state` you persisted) for a SocialUser. */
|
|
48
|
+
callback(code: string, state?: string): Promise<SocialUser>;
|
|
49
|
+
}
|
|
50
|
+
export {};
|
|
@@ -0,0 +1,73 @@
|
|
|
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.SocialiteManager = void 0;
|
|
7
|
+
const node_crypto_1 = __importDefault(require("node:crypto"));
|
|
8
|
+
const ProviderName_1 = require("../../domain/value-objects/ProviderName");
|
|
9
|
+
const ProviderFactory_1 = require("../../infrastructure/providers/ProviderFactory");
|
|
10
|
+
const FetchHttpClient_1 = require("../../infrastructure/http/FetchHttpClient");
|
|
11
|
+
const MemoryStateStore_1 = require("../../infrastructure/http/MemoryStateStore");
|
|
12
|
+
const SocialiteError_1 = require("../../domain/errors/SocialiteError");
|
|
13
|
+
/**
|
|
14
|
+
* Application Service: SocialiteManager
|
|
15
|
+
*
|
|
16
|
+
* The public facade of the SDK. It orchestrates domain contracts and
|
|
17
|
+
* infrastructure adapters but contains no provider-specific HTTP logic
|
|
18
|
+
* itself -- that all lives behind OAuthProviderContract implementations.
|
|
19
|
+
*
|
|
20
|
+
* Usage:
|
|
21
|
+
* const socialite = Socialite.create({ google: {...}, github: {...} });
|
|
22
|
+
* const { url, state } = socialite.driver("google").redirect();
|
|
23
|
+
* // ...later, in your OAuth callback route:
|
|
24
|
+
* const user = await socialite.driver("google").callback(code, state);
|
|
25
|
+
*/
|
|
26
|
+
class SocialiteManager {
|
|
27
|
+
constructor(config, http = new FetchHttpClient_1.FetchHttpClient(), stateStore = new MemoryStateStore_1.MemoryStateStore()) {
|
|
28
|
+
this.config = config;
|
|
29
|
+
this.http = http;
|
|
30
|
+
this.stateStore = stateStore;
|
|
31
|
+
this.cache = new Map();
|
|
32
|
+
}
|
|
33
|
+
/** Resolve (and memoize) the provider identified by `name`. */
|
|
34
|
+
driver(name) {
|
|
35
|
+
if (!(0, ProviderName_1.isSupportedProvider)(name)) {
|
|
36
|
+
throw new SocialiteError_1.UnsupportedProviderError(name);
|
|
37
|
+
}
|
|
38
|
+
if (!this.cache.has(name)) {
|
|
39
|
+
const providerConfig = this.config[name];
|
|
40
|
+
if (!providerConfig) {
|
|
41
|
+
throw new SocialiteError_1.ProviderNotConfiguredError(name);
|
|
42
|
+
}
|
|
43
|
+
this.cache.set(name, ProviderFactory_1.ProviderFactory.make(name, providerConfig, this.http, this.stateStore));
|
|
44
|
+
}
|
|
45
|
+
return new ProviderFacade(this.cache.get(name));
|
|
46
|
+
}
|
|
47
|
+
/** List provider names currently configured with credentials. */
|
|
48
|
+
configuredProviders() {
|
|
49
|
+
return Object.keys(this.config).filter((key) => Boolean(this.config[key]));
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
exports.SocialiteManager = SocialiteManager;
|
|
53
|
+
/**
|
|
54
|
+
* Thin per-request facade returned by `driver()`, giving callers a small,
|
|
55
|
+
* readable API surface (`redirect()` / `callback()`) instead of exposing
|
|
56
|
+
* the full OAuthProviderContract.
|
|
57
|
+
*/
|
|
58
|
+
class ProviderFacade {
|
|
59
|
+
constructor(provider) {
|
|
60
|
+
this.provider = provider;
|
|
61
|
+
}
|
|
62
|
+
/** Step 1: build the URL to redirect the user to, plus a state token to persist. */
|
|
63
|
+
redirect() {
|
|
64
|
+
const state = node_crypto_1.default.randomBytes(16).toString("hex");
|
|
65
|
+
const url = this.provider.getAuthorizationUrl(state);
|
|
66
|
+
return { url, state };
|
|
67
|
+
}
|
|
68
|
+
/** Step 2: exchange the callback's `code` (+ the `state` you persisted) for a SocialUser. */
|
|
69
|
+
callback(code, state) {
|
|
70
|
+
return this.provider.user(code, state);
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
//# sourceMappingURL=SocialiteManager.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"SocialiteManager.js","sourceRoot":"","sources":["../../../src/application/services/SocialiteManager.ts"],"names":[],"mappings":";;;;;;AAAA,8DAAiC;AAKjC,0EAA4F;AAE5F,oFAAiF;AACjF,+EAA4E;AAC5E,iFAA8E;AAC9E,uEAA0G;AAS1G;;;;;;;;;;;;GAYG;AACH,MAAa,gBAAgB;IAG3B,YACmB,MAAuB,EACvB,OAA2B,IAAI,iCAAe,EAAE,EAChD,aAAiC,IAAI,mCAAgB,EAAE;QAFvD,WAAM,GAAN,MAAM,CAAiB;QACvB,SAAI,GAAJ,IAAI,CAA4C;QAChD,eAAU,GAAV,UAAU,CAA6C;QALzD,UAAK,GAAG,IAAI,GAAG,EAAuC,CAAC;IAMrE,CAAC;IAEJ,+DAA+D;IAC/D,MAAM,CAAC,IAAY;QACjB,IAAI,CAAC,IAAA,kCAAmB,EAAC,IAAI,CAAC,EAAE,CAAC;YAC/B,MAAM,IAAI,yCAAwB,CAAC,IAAI,CAAC,CAAC;QAC3C,CAAC;QAED,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,CAAC;YAC1B,MAAM,cAAc,GAAG,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC;YACzC,IAAI,CAAC,cAAc,EAAE,CAAC;gBACpB,MAAM,IAAI,2CAA0B,CAAC,IAAI,CAAC,CAAC;YAC7C,CAAC;YACD,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,IAAI,EAAE,iCAAe,CAAC,IAAI,CAAC,IAAI,EAAE,cAAc,EAAE,IAAI,CAAC,IAAI,EAAE,IAAI,CAAC,UAAU,CAAC,CAAC,CAAC;QAC/F,CAAC;QAED,OAAO,IAAI,cAAc,CAAC,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,IAAI,CAAE,CAAC,CAAC;IACnD,CAAC;IAED,iEAAiE;IACjE,mBAAmB;QACjB,OAAQ,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,MAAM,CAAoB,CAAC,MAAM,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC,OAAO,CAAC,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC;IACjG,CAAC;CACF;AA9BD,4CA8BC;AAED;;;;GAIG;AACH,MAAM,cAAc;IAClB,YAA6B,QAA+B;QAA/B,aAAQ,GAAR,QAAQ,CAAuB;IAAG,CAAC;IAEhE,oFAAoF;IACpF,QAAQ;QACN,MAAM,KAAK,GAAG,qBAAM,CAAC,WAAW,CAAC,EAAE,CAAC,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC;QACrD,MAAM,GAAG,GAAG,IAAI,CAAC,QAAQ,CAAC,mBAAmB,CAAC,KAAK,CAAC,CAAC;QACrD,OAAO,EAAE,GAAG,EAAE,KAAK,EAAE,CAAC;IACxB,CAAC;IAED,6FAA6F;IAC7F,QAAQ,CAAC,IAAY,EAAE,KAAc;QACnC,OAAO,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,IAAI,EAAE,KAAK,CAAC,CAAC;IACzC,CAAC;CACF"}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Domain Contract (Port): HttpClientContract
|
|
3
|
+
*
|
|
4
|
+
* The domain/application layers should never call `fetch` directly.
|
|
5
|
+
* They depend on this abstraction so the actual HTTP implementation
|
|
6
|
+
* (native fetch, axios, a test double, ...) stays an infrastructure
|
|
7
|
+
* concern and is fully swappable/mockable.
|
|
8
|
+
*/
|
|
9
|
+
export interface 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
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"HttpClientContract.js","sourceRoot":"","sources":["../../../src/domain/contracts/HttpClientContract.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import { SocialUser } from "../entities/SocialUser";
|
|
2
|
+
/**
|
|
3
|
+
* Domain Contract (Port): OAuthProviderContract
|
|
4
|
+
*
|
|
5
|
+
* Defines the behaviour every social login provider must expose.
|
|
6
|
+
* The application layer only ever depends on this interface, never on
|
|
7
|
+
* a concrete provider class -- that's what lets us swap/add providers
|
|
8
|
+
* (infrastructure) without touching application logic (Dependency
|
|
9
|
+
* Inversion Principle).
|
|
10
|
+
*/
|
|
11
|
+
export interface OAuthProviderContract {
|
|
12
|
+
/** Unique key such as "google", "github", etc. */
|
|
13
|
+
readonly name: string;
|
|
14
|
+
/**
|
|
15
|
+
* Build the URL the end-user should be redirected to in order to
|
|
16
|
+
* grant consent. `state` is used for CSRF protection and, for
|
|
17
|
+
* PKCE-based providers, a `codeVerifier` is generated/stored internally.
|
|
18
|
+
*/
|
|
19
|
+
getAuthorizationUrl(state: string): string;
|
|
20
|
+
/** Exchange a temporary `code` (from the redirect callback) for tokens. */
|
|
21
|
+
getAccessToken(code: string, state?: string): Promise<import("../value-objects/AccessTokenResult").AccessTokenResult>;
|
|
22
|
+
/** Fetch the raw profile payload using a valid access token. */
|
|
23
|
+
getUserByToken(accessToken: string): Promise<Record<string, unknown>>;
|
|
24
|
+
/** Map a raw provider profile + token result into the domain SocialUser entity. */
|
|
25
|
+
mapToSocialUser(raw: Record<string, unknown>, token: import("../value-objects/AccessTokenResult").AccessTokenResult): SocialUser;
|
|
26
|
+
/** Convenience orchestration: code -> token -> profile -> SocialUser. */
|
|
27
|
+
user(code: string, state?: string): Promise<SocialUser>;
|
|
28
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"OAuthProviderContract.js","sourceRoot":"","sources":["../../../src/domain/contracts/OAuthProviderContract.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Domain Contract (Port): StateStoreContract
|
|
3
|
+
*
|
|
4
|
+
* OAuth "state" (CSRF token) and PKCE "code_verifier" values must be
|
|
5
|
+
* persisted between the redirect request and the callback request.
|
|
6
|
+
* In a real HTTP server this is usually backed by a session or cache;
|
|
7
|
+
* consumers of the SDK can provide their own implementation (e.g. Redis,
|
|
8
|
+
* express-session) instead of the in-memory default.
|
|
9
|
+
*/
|
|
10
|
+
export interface StateStoreContract {
|
|
11
|
+
put(state: string, codeVerifier: string | null): Promise<void> | void;
|
|
12
|
+
pull(state: string): Promise<string | null> | string | null;
|
|
13
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"StateStoreContract.js","sourceRoot":"","sources":["../../../src/domain/contracts/StateStoreContract.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Domain Entity: SocialUser
|
|
3
|
+
*
|
|
4
|
+
* A provider-agnostic representation of an authenticated user.
|
|
5
|
+
* Every concrete provider maps its own raw profile payload into this shape,
|
|
6
|
+
* so application code never has to deal with provider-specific fields.
|
|
7
|
+
*/
|
|
8
|
+
export interface SocialUserProps {
|
|
9
|
+
id: string;
|
|
10
|
+
nickname: string | null;
|
|
11
|
+
name: string | null;
|
|
12
|
+
email: string | null;
|
|
13
|
+
avatar: string | null;
|
|
14
|
+
provider: string;
|
|
15
|
+
accessToken: string;
|
|
16
|
+
refreshToken: string | null;
|
|
17
|
+
expiresIn: number | null;
|
|
18
|
+
/** The untouched payload returned by the provider, kept for edge cases. */
|
|
19
|
+
raw: Record<string, unknown>;
|
|
20
|
+
}
|
|
21
|
+
export declare class SocialUser {
|
|
22
|
+
readonly id: string;
|
|
23
|
+
readonly nickname: string | null;
|
|
24
|
+
readonly name: string | null;
|
|
25
|
+
readonly email: string | null;
|
|
26
|
+
readonly avatar: string | null;
|
|
27
|
+
readonly provider: string;
|
|
28
|
+
readonly accessToken: string;
|
|
29
|
+
readonly refreshToken: string | null;
|
|
30
|
+
readonly expiresIn: number | null;
|
|
31
|
+
readonly raw: Record<string, unknown>;
|
|
32
|
+
constructor(props: SocialUserProps);
|
|
33
|
+
toJSON(): Omit<SocialUserProps, "raw"> & {
|
|
34
|
+
raw: Record<string, unknown>;
|
|
35
|
+
};
|
|
36
|
+
}
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.SocialUser = void 0;
|
|
4
|
+
class SocialUser {
|
|
5
|
+
constructor(props) {
|
|
6
|
+
this.id = props.id;
|
|
7
|
+
this.nickname = props.nickname;
|
|
8
|
+
this.name = props.name;
|
|
9
|
+
this.email = props.email;
|
|
10
|
+
this.avatar = props.avatar;
|
|
11
|
+
this.provider = props.provider;
|
|
12
|
+
this.accessToken = props.accessToken;
|
|
13
|
+
this.refreshToken = props.refreshToken;
|
|
14
|
+
this.expiresIn = props.expiresIn;
|
|
15
|
+
this.raw = props.raw;
|
|
16
|
+
}
|
|
17
|
+
toJSON() {
|
|
18
|
+
return {
|
|
19
|
+
id: this.id,
|
|
20
|
+
nickname: this.nickname,
|
|
21
|
+
name: this.name,
|
|
22
|
+
email: this.email,
|
|
23
|
+
avatar: this.avatar,
|
|
24
|
+
provider: this.provider,
|
|
25
|
+
accessToken: this.accessToken,
|
|
26
|
+
refreshToken: this.refreshToken,
|
|
27
|
+
expiresIn: this.expiresIn,
|
|
28
|
+
raw: this.raw,
|
|
29
|
+
};
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
exports.SocialUser = SocialUser;
|
|
33
|
+
//# sourceMappingURL=SocialUser.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"SocialUser.js","sourceRoot":"","sources":["../../../src/domain/entities/SocialUser.ts"],"names":[],"mappings":";;;AAqBA,MAAa,UAAU;IAYrB,YAAY,KAAsB;QAChC,IAAI,CAAC,EAAE,GAAG,KAAK,CAAC,EAAE,CAAC;QACnB,IAAI,CAAC,QAAQ,GAAG,KAAK,CAAC,QAAQ,CAAC;QAC/B,IAAI,CAAC,IAAI,GAAG,KAAK,CAAC,IAAI,CAAC;QACvB,IAAI,CAAC,KAAK,GAAG,KAAK,CAAC,KAAK,CAAC;QACzB,IAAI,CAAC,MAAM,GAAG,KAAK,CAAC,MAAM,CAAC;QAC3B,IAAI,CAAC,QAAQ,GAAG,KAAK,CAAC,QAAQ,CAAC;QAC/B,IAAI,CAAC,WAAW,GAAG,KAAK,CAAC,WAAW,CAAC;QACrC,IAAI,CAAC,YAAY,GAAG,KAAK,CAAC,YAAY,CAAC;QACvC,IAAI,CAAC,SAAS,GAAG,KAAK,CAAC,SAAS,CAAC;QACjC,IAAI,CAAC,GAAG,GAAG,KAAK,CAAC,GAAG,CAAC;IACvB,CAAC;IAED,MAAM;QACJ,OAAO;YACL,EAAE,EAAE,IAAI,CAAC,EAAE;YACX,QAAQ,EAAE,IAAI,CAAC,QAAQ;YACvB,IAAI,EAAE,IAAI,CAAC,IAAI;YACf,KAAK,EAAE,IAAI,CAAC,KAAK;YACjB,MAAM,EAAE,IAAI,CAAC,MAAM;YACnB,QAAQ,EAAE,IAAI,CAAC,QAAQ;YACvB,WAAW,EAAE,IAAI,CAAC,WAAW;YAC7B,YAAY,EAAE,IAAI,CAAC,YAAY;YAC/B,SAAS,EAAE,IAAI,CAAC,SAAS;YACzB,GAAG,EAAE,IAAI,CAAC,GAAG;SACd,CAAC;IACJ,CAAC;CACF;AAvCD,gCAuCC"}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
export declare class SocialiteError extends Error {
|
|
2
|
+
constructor(message: string);
|
|
3
|
+
}
|
|
4
|
+
export declare class InvalidStateError extends SocialiteError {
|
|
5
|
+
constructor();
|
|
6
|
+
}
|
|
7
|
+
export declare class ProviderNotConfiguredError extends SocialiteError {
|
|
8
|
+
constructor(provider: string);
|
|
9
|
+
}
|
|
10
|
+
export declare class UnsupportedProviderError extends SocialiteError {
|
|
11
|
+
constructor(provider: string);
|
|
12
|
+
}
|
|
13
|
+
export declare class TokenExchangeError extends SocialiteError {
|
|
14
|
+
constructor(provider: string, details: string);
|
|
15
|
+
}
|
|
16
|
+
export declare class UserFetchError extends SocialiteError {
|
|
17
|
+
constructor(provider: string, details: string);
|
|
18
|
+
}
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.UserFetchError = exports.TokenExchangeError = exports.UnsupportedProviderError = exports.ProviderNotConfiguredError = exports.InvalidStateError = exports.SocialiteError = void 0;
|
|
4
|
+
class SocialiteError extends Error {
|
|
5
|
+
constructor(message) {
|
|
6
|
+
super(message);
|
|
7
|
+
this.name = "SocialiteError";
|
|
8
|
+
}
|
|
9
|
+
}
|
|
10
|
+
exports.SocialiteError = SocialiteError;
|
|
11
|
+
class InvalidStateError extends SocialiteError {
|
|
12
|
+
constructor() {
|
|
13
|
+
super("The OAuth 'state' parameter is invalid or has expired. Possible CSRF attempt.");
|
|
14
|
+
this.name = "InvalidStateError";
|
|
15
|
+
}
|
|
16
|
+
}
|
|
17
|
+
exports.InvalidStateError = InvalidStateError;
|
|
18
|
+
class ProviderNotConfiguredError extends SocialiteError {
|
|
19
|
+
constructor(provider) {
|
|
20
|
+
super(`Provider "${provider}" is not configured. Pass its clientId/clientSecret/redirectUri to Socialite.create().`);
|
|
21
|
+
this.name = "ProviderNotConfiguredError";
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
exports.ProviderNotConfiguredError = ProviderNotConfiguredError;
|
|
25
|
+
class UnsupportedProviderError extends SocialiteError {
|
|
26
|
+
constructor(provider) {
|
|
27
|
+
super(`Provider "${provider}" is not a supported Socialite driver.`);
|
|
28
|
+
this.name = "UnsupportedProviderError";
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
exports.UnsupportedProviderError = UnsupportedProviderError;
|
|
32
|
+
class TokenExchangeError extends SocialiteError {
|
|
33
|
+
constructor(provider, details) {
|
|
34
|
+
super(`Failed to exchange authorization code for an access token with "${provider}": ${details}`);
|
|
35
|
+
this.name = "TokenExchangeError";
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
exports.TokenExchangeError = TokenExchangeError;
|
|
39
|
+
class UserFetchError extends SocialiteError {
|
|
40
|
+
constructor(provider, details) {
|
|
41
|
+
super(`Failed to fetch user profile from "${provider}": ${details}`);
|
|
42
|
+
this.name = "UserFetchError";
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
exports.UserFetchError = UserFetchError;
|
|
46
|
+
//# sourceMappingURL=SocialiteError.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"SocialiteError.js","sourceRoot":"","sources":["../../../src/domain/errors/SocialiteError.ts"],"names":[],"mappings":";;;AAAA,MAAa,cAAe,SAAQ,KAAK;IACvC,YAAY,OAAe;QACzB,KAAK,CAAC,OAAO,CAAC,CAAC;QACf,IAAI,CAAC,IAAI,GAAG,gBAAgB,CAAC;IAC/B,CAAC;CACF;AALD,wCAKC;AAED,MAAa,iBAAkB,SAAQ,cAAc;IACnD;QACE,KAAK,CAAC,+EAA+E,CAAC,CAAC;QACvF,IAAI,CAAC,IAAI,GAAG,mBAAmB,CAAC;IAClC,CAAC;CACF;AALD,8CAKC;AAED,MAAa,0BAA2B,SAAQ,cAAc;IAC5D,YAAY,QAAgB;QAC1B,KAAK,CAAC,aAAa,QAAQ,wFAAwF,CAAC,CAAC;QACrH,IAAI,CAAC,IAAI,GAAG,4BAA4B,CAAC;IAC3C,CAAC;CACF;AALD,gEAKC;AAED,MAAa,wBAAyB,SAAQ,cAAc;IAC1D,YAAY,QAAgB;QAC1B,KAAK,CAAC,aAAa,QAAQ,wCAAwC,CAAC,CAAC;QACrE,IAAI,CAAC,IAAI,GAAG,0BAA0B,CAAC;IACzC,CAAC;CACF;AALD,4DAKC;AAED,MAAa,kBAAmB,SAAQ,cAAc;IACpD,YAAY,QAAgB,EAAE,OAAe;QAC3C,KAAK,CAAC,mEAAmE,QAAQ,MAAM,OAAO,EAAE,CAAC,CAAC;QAClG,IAAI,CAAC,IAAI,GAAG,oBAAoB,CAAC;IACnC,CAAC;CACF;AALD,gDAKC;AAED,MAAa,cAAe,SAAQ,cAAc;IAChD,YAAY,QAAgB,EAAE,OAAe;QAC3C,KAAK,CAAC,sCAAsC,QAAQ,MAAM,OAAO,EAAE,CAAC,CAAC;QACrE,IAAI,CAAC,IAAI,GAAG,gBAAgB,CAAC;IAC/B,CAAC;CACF;AALD,wCAKC"}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Value Object: AccessTokenResult
|
|
3
|
+
*
|
|
4
|
+
* Immutable representation of the token endpoint response. Value objects
|
|
5
|
+
* in DDD have no identity of their own -- two instances with the same
|
|
6
|
+
* data are considered equal/interchangeable.
|
|
7
|
+
*/
|
|
8
|
+
export declare class AccessTokenResult {
|
|
9
|
+
readonly accessToken: string;
|
|
10
|
+
readonly refreshToken: string | null;
|
|
11
|
+
readonly expiresIn: number | null;
|
|
12
|
+
readonly tokenType: string | null;
|
|
13
|
+
readonly raw: Record<string, unknown>;
|
|
14
|
+
constructor(accessToken: string, refreshToken: string | null, expiresIn: number | null, tokenType: string | null, raw: Record<string, unknown>);
|
|
15
|
+
static fromRaw(raw: Record<string, unknown>): AccessTokenResult;
|
|
16
|
+
}
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.AccessTokenResult = void 0;
|
|
4
|
+
/**
|
|
5
|
+
* Value Object: AccessTokenResult
|
|
6
|
+
*
|
|
7
|
+
* Immutable representation of the token endpoint response. Value objects
|
|
8
|
+
* in DDD have no identity of their own -- two instances with the same
|
|
9
|
+
* data are considered equal/interchangeable.
|
|
10
|
+
*/
|
|
11
|
+
class AccessTokenResult {
|
|
12
|
+
constructor(accessToken, refreshToken, expiresIn, tokenType, raw) {
|
|
13
|
+
this.accessToken = accessToken;
|
|
14
|
+
this.refreshToken = refreshToken;
|
|
15
|
+
this.expiresIn = expiresIn;
|
|
16
|
+
this.tokenType = tokenType;
|
|
17
|
+
this.raw = raw;
|
|
18
|
+
}
|
|
19
|
+
static fromRaw(raw) {
|
|
20
|
+
const accessToken = raw.access_token ?? raw.accessToken;
|
|
21
|
+
if (!accessToken) {
|
|
22
|
+
throw new Error("Token response did not contain an access_token field");
|
|
23
|
+
}
|
|
24
|
+
return new AccessTokenResult(accessToken, raw.refresh_token ?? null, typeof raw.expires_in === "number" ? raw.expires_in : null, raw.token_type ?? null, raw);
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
exports.AccessTokenResult = AccessTokenResult;
|
|
28
|
+
//# sourceMappingURL=AccessTokenResult.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"AccessTokenResult.js","sourceRoot":"","sources":["../../../src/domain/value-objects/AccessTokenResult.ts"],"names":[],"mappings":";;;AAAA;;;;;;GAMG;AACH,MAAa,iBAAiB;IAC5B,YACkB,WAAmB,EACnB,YAA2B,EAC3B,SAAwB,EACxB,SAAwB,EACxB,GAA4B;QAJ5B,gBAAW,GAAX,WAAW,CAAQ;QACnB,iBAAY,GAAZ,YAAY,CAAe;QAC3B,cAAS,GAAT,SAAS,CAAe;QACxB,cAAS,GAAT,SAAS,CAAe;QACxB,QAAG,GAAH,GAAG,CAAyB;IAC3C,CAAC;IAEJ,MAAM,CAAC,OAAO,CAAC,GAA4B;QACzC,MAAM,WAAW,GAAI,GAAG,CAAC,YAAuB,IAAK,GAAG,CAAC,WAAsB,CAAC;QAChF,IAAI,CAAC,WAAW,EAAE,CAAC;YACjB,MAAM,IAAI,KAAK,CAAC,sDAAsD,CAAC,CAAC;QAC1E,CAAC;QACD,OAAO,IAAI,iBAAiB,CAC1B,WAAW,EACV,GAAG,CAAC,aAAwB,IAAI,IAAI,EACrC,OAAO,GAAG,CAAC,UAAU,KAAK,QAAQ,CAAC,CAAC,CAAC,GAAG,CAAC,UAAU,CAAC,CAAC,CAAC,IAAI,EACzD,GAAG,CAAC,UAAqB,IAAI,IAAI,EAClC,GAAG,CACJ,CAAC;IACJ,CAAC;CACF;AAtBD,8CAsBC"}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Value Object: ProviderName
|
|
3
|
+
*
|
|
4
|
+
* Restricts provider identifiers to a known, closed set so that typos
|
|
5
|
+
* ("gogle") fail fast at the type level and at runtime.
|
|
6
|
+
*/
|
|
7
|
+
export declare const SUPPORTED_PROVIDERS: readonly ["google", "microsoft", "facebook", "github", "twitter", "linkedin"];
|
|
8
|
+
export type ProviderName = (typeof SUPPORTED_PROVIDERS)[number];
|
|
9
|
+
export declare function isSupportedProvider(value: string): value is ProviderName;
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.SUPPORTED_PROVIDERS = void 0;
|
|
4
|
+
exports.isSupportedProvider = isSupportedProvider;
|
|
5
|
+
/**
|
|
6
|
+
* Value Object: ProviderName
|
|
7
|
+
*
|
|
8
|
+
* Restricts provider identifiers to a known, closed set so that typos
|
|
9
|
+
* ("gogle") fail fast at the type level and at runtime.
|
|
10
|
+
*/
|
|
11
|
+
exports.SUPPORTED_PROVIDERS = [
|
|
12
|
+
"google",
|
|
13
|
+
"microsoft",
|
|
14
|
+
"facebook",
|
|
15
|
+
"github",
|
|
16
|
+
"twitter",
|
|
17
|
+
"linkedin",
|
|
18
|
+
];
|
|
19
|
+
function isSupportedProvider(value) {
|
|
20
|
+
return exports.SUPPORTED_PROVIDERS.includes(value);
|
|
21
|
+
}
|
|
22
|
+
//# sourceMappingURL=ProviderName.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ProviderName.js","sourceRoot":"","sources":["../../../src/domain/value-objects/ProviderName.ts"],"names":[],"mappings":";;;AAiBA,kDAEC;AAnBD;;;;;GAKG;AACU,QAAA,mBAAmB,GAAG;IACjC,QAAQ;IACR,WAAW;IACX,UAAU;IACV,QAAQ;IACR,SAAS;IACT,UAAU;CACF,CAAC;AAIX,SAAgB,mBAAmB,CAAC,KAAa;IAC/C,OAAQ,2BAAyC,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC;AACpE,CAAC"}
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
import { SocialiteConfig } from "./application/dto/ProviderConfig";
|
|
2
|
+
import { SocialiteManager } from "./application/services/SocialiteManager";
|
|
3
|
+
import { HttpClientContract } from "./domain/contracts/HttpClientContract";
|
|
4
|
+
import { StateStoreContract } from "./domain/contracts/StateStoreContract";
|
|
5
|
+
/**
|
|
6
|
+
* Socialite -- public factory.
|
|
7
|
+
*
|
|
8
|
+
* const socialite = Socialite.create({
|
|
9
|
+
* google: { clientId, clientSecret, redirectUri },
|
|
10
|
+
* github: { clientId, clientSecret, redirectUri },
|
|
11
|
+
* });
|
|
12
|
+
*/
|
|
13
|
+
export declare class Socialite {
|
|
14
|
+
static create(config: SocialiteConfig, http?: HttpClientContract, stateStore?: StateStoreContract): SocialiteManager;
|
|
15
|
+
}
|
|
16
|
+
export { SocialUser } from "./domain/entities/SocialUser";
|
|
17
|
+
export type { SocialUserProps } from "./domain/entities/SocialUser";
|
|
18
|
+
export { AccessTokenResult } from "./domain/value-objects/AccessTokenResult";
|
|
19
|
+
export { SUPPORTED_PROVIDERS, isSupportedProvider } from "./domain/value-objects/ProviderName";
|
|
20
|
+
export type { ProviderName } from "./domain/value-objects/ProviderName";
|
|
21
|
+
export type { OAuthProviderContract } from "./domain/contracts/OAuthProviderContract";
|
|
22
|
+
export type { HttpClientContract } from "./domain/contracts/HttpClientContract";
|
|
23
|
+
export type { StateStoreContract } from "./domain/contracts/StateStoreContract";
|
|
24
|
+
export { SocialiteError, InvalidStateError, ProviderNotConfiguredError, UnsupportedProviderError, TokenExchangeError, UserFetchError, } from "./domain/errors/SocialiteError";
|
|
25
|
+
export { SocialiteManager } from "./application/services/SocialiteManager";
|
|
26
|
+
export type { RedirectResult } from "./application/services/SocialiteManager";
|
|
27
|
+
export type { ProviderConfig, SocialiteConfig } from "./application/dto/ProviderConfig";
|
|
28
|
+
export { FetchHttpClient } from "./infrastructure/http/FetchHttpClient";
|
|
29
|
+
export { MemoryStateStore } from "./infrastructure/http/MemoryStateStore";
|
|
30
|
+
export { ProviderFactory } from "./infrastructure/providers/ProviderFactory";
|
|
31
|
+
export { GoogleProvider } from "./infrastructure/providers/GoogleProvider";
|
|
32
|
+
export { MicrosoftProvider } from "./infrastructure/providers/MicrosoftProvider";
|
|
33
|
+
export { FacebookProvider } from "./infrastructure/providers/FacebookProvider";
|
|
34
|
+
export { GithubProvider } from "./infrastructure/providers/GithubProvider";
|
|
35
|
+
export { TwitterProvider } from "./infrastructure/providers/TwitterProvider";
|
|
36
|
+
export { LinkedinProvider } from "./infrastructure/providers/LinkedinProvider";
|