@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
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.MicrosoftProvider = void 0;
|
|
4
|
+
const AbstractProvider_1 = require("./AbstractProvider");
|
|
5
|
+
const SocialUser_1 = require("../../domain/entities/SocialUser");
|
|
6
|
+
class MicrosoftProvider extends AbstractProvider_1.AbstractProvider {
|
|
7
|
+
constructor() {
|
|
8
|
+
super(...arguments);
|
|
9
|
+
this.name = "microsoft";
|
|
10
|
+
// "common" allows both personal Microsoft accounts and work/school (Azure AD) accounts.
|
|
11
|
+
this.authorizeUrl = "https://login.microsoftonline.com/common/oauth2/v2.0/authorize";
|
|
12
|
+
this.tokenUrl = "https://login.microsoftonline.com/common/oauth2/v2.0/token";
|
|
13
|
+
this.userUrl = "https://graph.microsoft.com/v1.0/me";
|
|
14
|
+
this.defaultScopes = ["openid", "profile", "email", "User.Read"];
|
|
15
|
+
}
|
|
16
|
+
mapToSocialUser(raw, token) {
|
|
17
|
+
return new SocialUser_1.SocialUser({
|
|
18
|
+
id: String(raw.id),
|
|
19
|
+
nickname: raw.userPrincipalName ?? null,
|
|
20
|
+
name: raw.displayName ?? null,
|
|
21
|
+
email: raw.mail ?? raw.userPrincipalName ?? null,
|
|
22
|
+
avatar: null, // Requires a separate call to /me/photo/$value; omitted to keep this call cheap.
|
|
23
|
+
provider: this.name,
|
|
24
|
+
accessToken: token.accessToken,
|
|
25
|
+
refreshToken: token.refreshToken,
|
|
26
|
+
expiresIn: token.expiresIn,
|
|
27
|
+
raw,
|
|
28
|
+
});
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
exports.MicrosoftProvider = MicrosoftProvider;
|
|
32
|
+
//# sourceMappingURL=MicrosoftProvider.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"MicrosoftProvider.js","sourceRoot":"","sources":["../../../src/infrastructure/providers/MicrosoftProvider.ts"],"names":[],"mappings":";;;AAAA,yDAAsD;AACtD,iEAA8D;AAG9D,MAAa,iBAAkB,SAAQ,mCAAgB;IAAvD;;QACW,SAAI,GAAG,WAAW,CAAC;QAC5B,wFAAwF;QACrE,iBAAY,GAAG,gEAAgE,CAAC;QAChF,aAAQ,GAAG,4DAA4D,CAAC;QACxE,YAAO,GAAG,qCAAqC,CAAC;QAChD,kBAAa,GAAG,CAAC,QAAQ,EAAE,SAAS,EAAE,OAAO,EAAE,WAAW,CAAC,CAAC;IAgBjF,CAAC;IAdC,eAAe,CAAC,GAA4B,EAAE,KAAwB;QACpE,OAAO,IAAI,uBAAU,CAAC;YACpB,EAAE,EAAE,MAAM,CAAC,GAAG,CAAC,EAAE,CAAC;YAClB,QAAQ,EAAG,GAAG,CAAC,iBAA4B,IAAI,IAAI;YACnD,IAAI,EAAG,GAAG,CAAC,WAAsB,IAAI,IAAI;YACzC,KAAK,EAAG,GAAG,CAAC,IAAe,IAAK,GAAG,CAAC,iBAA4B,IAAI,IAAI;YACxE,MAAM,EAAE,IAAI,EAAE,iFAAiF;YAC/F,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;AAtBD,8CAsBC"}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import { OAuthProviderContract } from "../../domain/contracts/OAuthProviderContract";
|
|
2
|
+
import { HttpClientContract } from "../../domain/contracts/HttpClientContract";
|
|
3
|
+
import { StateStoreContract } from "../../domain/contracts/StateStoreContract";
|
|
4
|
+
import { ProviderConfig } from "../../application/dto/ProviderConfig";
|
|
5
|
+
import { ProviderName } from "../../domain/value-objects/ProviderName";
|
|
6
|
+
/**
|
|
7
|
+
* Infrastructure Factory: ProviderFactory
|
|
8
|
+
*
|
|
9
|
+
* Encapsulates the mapping from a driver name string to the concrete
|
|
10
|
+
* class that implements it. This is the only place in the codebase
|
|
11
|
+
* that needs to change to register a brand-new provider.
|
|
12
|
+
*/
|
|
13
|
+
export declare class ProviderFactory {
|
|
14
|
+
static make(name: ProviderName, config: ProviderConfig, http: HttpClientContract, stateStore: StateStoreContract): OAuthProviderContract;
|
|
15
|
+
}
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.ProviderFactory = void 0;
|
|
4
|
+
const SocialiteError_1 = require("../../domain/errors/SocialiteError");
|
|
5
|
+
const GoogleProvider_1 = require("./GoogleProvider");
|
|
6
|
+
const MicrosoftProvider_1 = require("./MicrosoftProvider");
|
|
7
|
+
const FacebookProvider_1 = require("./FacebookProvider");
|
|
8
|
+
const GithubProvider_1 = require("./GithubProvider");
|
|
9
|
+
const TwitterProvider_1 = require("./TwitterProvider");
|
|
10
|
+
const LinkedinProvider_1 = require("./LinkedinProvider");
|
|
11
|
+
const PROVIDER_REGISTRY = {
|
|
12
|
+
google: GoogleProvider_1.GoogleProvider,
|
|
13
|
+
microsoft: MicrosoftProvider_1.MicrosoftProvider,
|
|
14
|
+
facebook: FacebookProvider_1.FacebookProvider,
|
|
15
|
+
github: GithubProvider_1.GithubProvider,
|
|
16
|
+
twitter: TwitterProvider_1.TwitterProvider,
|
|
17
|
+
linkedin: LinkedinProvider_1.LinkedinProvider,
|
|
18
|
+
};
|
|
19
|
+
/**
|
|
20
|
+
* Infrastructure Factory: ProviderFactory
|
|
21
|
+
*
|
|
22
|
+
* Encapsulates the mapping from a driver name string to the concrete
|
|
23
|
+
* class that implements it. This is the only place in the codebase
|
|
24
|
+
* that needs to change to register a brand-new provider.
|
|
25
|
+
*/
|
|
26
|
+
class ProviderFactory {
|
|
27
|
+
static make(name, config, http, stateStore) {
|
|
28
|
+
const Ctor = PROVIDER_REGISTRY[name];
|
|
29
|
+
if (!Ctor) {
|
|
30
|
+
throw new SocialiteError_1.UnsupportedProviderError(name);
|
|
31
|
+
}
|
|
32
|
+
return new Ctor(config, http, stateStore);
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
exports.ProviderFactory = ProviderFactory;
|
|
36
|
+
//# sourceMappingURL=ProviderFactory.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ProviderFactory.js","sourceRoot":"","sources":["../../../src/infrastructure/providers/ProviderFactory.ts"],"names":[],"mappings":";;;AAKA,uEAA8E;AAE9E,qDAAkD;AAClD,2DAAwD;AACxD,yDAAsD;AACtD,qDAAkD;AAClD,uDAAoD;AACpD,yDAAsD;AAQtD,MAAM,iBAAiB,GAAuC;IAC5D,MAAM,EAAE,+BAAc;IACtB,SAAS,EAAE,qCAAiB;IAC5B,QAAQ,EAAE,mCAAgB;IAC1B,MAAM,EAAE,+BAAc;IACtB,OAAO,EAAE,iCAAe;IACxB,QAAQ,EAAE,mCAAgB;CAC3B,CAAC;AAEF;;;;;;GAMG;AACH,MAAa,eAAe;IAC1B,MAAM,CAAC,IAAI,CACT,IAAkB,EAClB,MAAsB,EACtB,IAAwB,EACxB,UAA8B;QAE9B,MAAM,IAAI,GAAG,iBAAiB,CAAC,IAAI,CAAC,CAAC;QACrC,IAAI,CAAC,IAAI,EAAE,CAAC;YACV,MAAM,IAAI,yCAAwB,CAAC,IAAI,CAAC,CAAC;QAC3C,CAAC;QACD,OAAO,IAAI,IAAI,CAAC,MAAM,EAAE,IAAI,EAAE,UAAU,CAAC,CAAC;IAC5C,CAAC;CACF;AAbD,0CAaC"}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import { AbstractProvider } from "./AbstractProvider";
|
|
2
|
+
import { SocialUser } from "../../domain/entities/SocialUser";
|
|
3
|
+
import { AccessTokenResult } from "../../domain/value-objects/AccessTokenResult";
|
|
4
|
+
export declare class TwitterProvider extends AbstractProvider {
|
|
5
|
+
readonly name = "twitter";
|
|
6
|
+
protected readonly authorizeUrl = "https://twitter.com/i/oauth2/authorize";
|
|
7
|
+
protected readonly tokenUrl = "https://api.twitter.com/2/oauth2/token";
|
|
8
|
+
protected readonly userUrl = "https://api.twitter.com/2/users/me?user.fields=profile_image_url,username,name";
|
|
9
|
+
protected readonly defaultScopes: string[];
|
|
10
|
+
protected readonly usesPKCE = true;
|
|
11
|
+
protected tokenRequestHeaders(): Record<string, string>;
|
|
12
|
+
mapToSocialUser(raw: Record<string, unknown>, token: AccessTokenResult): SocialUser;
|
|
13
|
+
}
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.TwitterProvider = void 0;
|
|
4
|
+
const AbstractProvider_1 = require("./AbstractProvider");
|
|
5
|
+
const SocialUser_1 = require("../../domain/entities/SocialUser");
|
|
6
|
+
class TwitterProvider extends AbstractProvider_1.AbstractProvider {
|
|
7
|
+
constructor() {
|
|
8
|
+
super(...arguments);
|
|
9
|
+
this.name = "twitter";
|
|
10
|
+
this.authorizeUrl = "https://twitter.com/i/oauth2/authorize";
|
|
11
|
+
this.tokenUrl = "https://api.twitter.com/2/oauth2/token";
|
|
12
|
+
this.userUrl = "https://api.twitter.com/2/users/me?user.fields=profile_image_url,username,name";
|
|
13
|
+
this.defaultScopes = ["tweet.read", "users.read", "offline.access"];
|
|
14
|
+
// X (Twitter) OAuth 2.0 mandates PKCE for the authorization code grant.
|
|
15
|
+
this.usesPKCE = true;
|
|
16
|
+
}
|
|
17
|
+
// X's token endpoint authenticates confidential clients via HTTP Basic
|
|
18
|
+
// auth (base64 client_id:client_secret) rather than body parameters.
|
|
19
|
+
tokenRequestHeaders() {
|
|
20
|
+
const basic = Buffer.from(`${this.config.clientId}:${this.config.clientSecret}`).toString("base64");
|
|
21
|
+
return {
|
|
22
|
+
Accept: "application/json",
|
|
23
|
+
Authorization: `Basic ${basic}`,
|
|
24
|
+
};
|
|
25
|
+
}
|
|
26
|
+
mapToSocialUser(raw, token) {
|
|
27
|
+
const data = (raw.data ?? raw);
|
|
28
|
+
return new SocialUser_1.SocialUser({
|
|
29
|
+
id: String(data.id),
|
|
30
|
+
nickname: data.username ?? null,
|
|
31
|
+
name: data.name ?? null,
|
|
32
|
+
email: null, // X's API does not expose email through this endpoint.
|
|
33
|
+
avatar: data.profile_image_url ?? null,
|
|
34
|
+
provider: this.name,
|
|
35
|
+
accessToken: token.accessToken,
|
|
36
|
+
refreshToken: token.refreshToken,
|
|
37
|
+
expiresIn: token.expiresIn,
|
|
38
|
+
raw,
|
|
39
|
+
});
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
exports.TwitterProvider = TwitterProvider;
|
|
43
|
+
//# sourceMappingURL=TwitterProvider.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"TwitterProvider.js","sourceRoot":"","sources":["../../../src/infrastructure/providers/TwitterProvider.ts"],"names":[],"mappings":";;;AAAA,yDAAsD;AACtD,iEAA8D;AAG9D,MAAa,eAAgB,SAAQ,mCAAgB;IAArD;;QACW,SAAI,GAAG,SAAS,CAAC;QACP,iBAAY,GAAG,wCAAwC,CAAC;QACxD,aAAQ,GAAG,wCAAwC,CAAC;QACpD,YAAO,GAAG,gFAAgF,CAAC;QAC3F,kBAAa,GAAG,CAAC,YAAY,EAAE,YAAY,EAAE,gBAAgB,CAAC,CAAC;QAClF,wEAAwE;QACrD,aAAQ,GAAG,IAAI,CAAC;IA2BrC,CAAC;IAzBC,uEAAuE;IACvE,qEAAqE;IAC3D,mBAAmB;QAC3B,MAAM,KAAK,GAAG,MAAM,CAAC,IAAI,CAAC,GAAG,IAAI,CAAC,MAAM,CAAC,QAAQ,IAAI,IAAI,CAAC,MAAM,CAAC,YAAY,EAAE,CAAC,CAAC,QAAQ,CAAC,QAAQ,CAAC,CAAC;QACpG,OAAO;YACL,MAAM,EAAE,kBAAkB;YAC1B,aAAa,EAAE,SAAS,KAAK,EAAE;SAChC,CAAC;IACJ,CAAC;IAED,eAAe,CAAC,GAA4B,EAAE,KAAwB;QACpE,MAAM,IAAI,GAAG,CAAC,GAAG,CAAC,IAAI,IAAI,GAAG,CAA4B,CAAC;QAC1D,OAAO,IAAI,uBAAU,CAAC;YACpB,EAAE,EAAE,MAAM,CAAC,IAAI,CAAC,EAAE,CAAC;YACnB,QAAQ,EAAG,IAAI,CAAC,QAAmB,IAAI,IAAI;YAC3C,IAAI,EAAG,IAAI,CAAC,IAAe,IAAI,IAAI;YACnC,KAAK,EAAE,IAAI,EAAE,uDAAuD;YACpE,MAAM,EAAG,IAAI,CAAC,iBAA4B,IAAI,IAAI;YAClD,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;AAlCD,0CAkCC"}
|
package/package.json
ADDED
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@bactv/socialite",
|
|
3
|
+
"version": "1.0.0",
|
|
4
|
+
"description": "A DDD-structured Node.js SDK for social login (OAuth2) across Google, Microsoft, Facebook, GitHub, Twitter/X and LinkedIn.",
|
|
5
|
+
"main": "./dist/index.js",
|
|
6
|
+
"module": "./dist/index.mjs",
|
|
7
|
+
"types": "./dist/index.d.ts",
|
|
8
|
+
"exports": {
|
|
9
|
+
".": {
|
|
10
|
+
"types": "./dist/index.d.ts",
|
|
11
|
+
"import": "./dist/index.mjs",
|
|
12
|
+
"require": "./dist/index.js"
|
|
13
|
+
}
|
|
14
|
+
},
|
|
15
|
+
"type": "commonjs",
|
|
16
|
+
"engines": {
|
|
17
|
+
"node": ">=18.0.0"
|
|
18
|
+
},
|
|
19
|
+
"files": [
|
|
20
|
+
"dist"
|
|
21
|
+
],
|
|
22
|
+
"scripts": {
|
|
23
|
+
"build": "tsc -p tsconfig.json",
|
|
24
|
+
"dev": "tsc -w -p tsconfig.json",
|
|
25
|
+
"test": "tsc --module commonjs --target ES2021 --esModuleInterop --outDir dist-tests --rootDir . src/index.ts tests/*.test.ts && node --test dist-tests/tests/*.test.js",
|
|
26
|
+
"prepublishOnly": "npm run build"
|
|
27
|
+
},
|
|
28
|
+
"keywords": [
|
|
29
|
+
"oauth",
|
|
30
|
+
"oauth2",
|
|
31
|
+
"social-login",
|
|
32
|
+
"google",
|
|
33
|
+
"microsoft",
|
|
34
|
+
"facebook",
|
|
35
|
+
"github",
|
|
36
|
+
"twitter",
|
|
37
|
+
"linkedin",
|
|
38
|
+
"ddd"
|
|
39
|
+
],
|
|
40
|
+
"author": "Bac Truong Van<bactruongvan17@gmail.com>",
|
|
41
|
+
"license": "MIT",
|
|
42
|
+
"devDependencies": {
|
|
43
|
+
"typescript": "^5.5.4",
|
|
44
|
+
"@types/node": "^20.14.0",
|
|
45
|
+
"ts-node": "^10.9.2"
|
|
46
|
+
}
|
|
47
|
+
}
|