express-authenticators
Advanced tools
Comparing version 0.1.5 to 0.2.0-experiiment-1
@@ -0,1 +1,2 @@ | ||
import type { BinaryLike } from 'crypto'; | ||
export declare const decodeSessionData: (raw?: string) => any; | ||
@@ -6,1 +7,2 @@ export declare const encodeSessionData: { | ||
}; | ||
export declare const safeCompare: (a?: BinaryLike, b?: BinaryLike) => boolean; |
"use strict"; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
exports.encodeSessionData = exports.decodeSessionData = void 0; | ||
exports.safeCompare = exports.encodeSessionData = exports.decodeSessionData = void 0; | ||
const crypto_1 = require("crypto"); | ||
const decodeSessionData = (raw) => { | ||
@@ -14,2 +15,11 @@ try { | ||
exports.encodeSessionData = JSON.stringify; | ||
const safeCompare = (a, b) => { | ||
if (typeof a !== 'string' || typeof b !== 'string') | ||
return false; | ||
const key = (0, crypto_1.randomBytes)(32); | ||
const ha = (0, crypto_1.createHmac)('sha256', key).update(a).digest(); | ||
const hb = (0, crypto_1.createHmac)('sha256', key).update(b).digest(); | ||
return ha.length === hb.length && (0, crypto_1.timingSafeEqual)(Buffer.from(ha), Buffer.from(hb)) && a === b; | ||
}; | ||
exports.safeCompare = safeCompare; | ||
//# sourceMappingURL=lib.js.map |
@@ -36,3 +36,3 @@ import { OAuthSigningMethod } from './oauthUtils'; | ||
authenticate({ store }: IStoreSession): Promise<string>; | ||
signAndFetch(url: string, options: IOAuthRequestOptions, tokenPayload?: IOAuthTokenPayload): any; | ||
signAndFetch(url: string, options: IOAuthRequestOptions, tokenPayload?: IOAuthTokenPayload): Promise<Response>; | ||
callback({ pop }: IPopSession, rawQuery: string): Promise<{ | ||
@@ -39,0 +39,0 @@ token: string; |
@@ -21,3 +21,2 @@ "use strict"; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
const node_fetch_1 = __importDefault(require("node-fetch")); | ||
const oauthUtils_1 = require("./oauthUtils"); | ||
@@ -53,3 +52,3 @@ const OAuthError_1 = __importDefault(require("./OAuthError")); | ||
signAndFetch(url, options, tokenPayload) { | ||
return (0, node_fetch_1.default)(`${url}${options.qs ? `?${new url_1.URLSearchParams(options.qs).toString()}` : ''}`, { | ||
return fetch(`${url}${options.qs ? `?${new url_1.URLSearchParams(options.qs).toString()}` : ''}`, { | ||
headers: Object.assign(Object.assign({}, options.headers), { Authorization: __classPrivateFieldGet(this, _OAuth_instances, "m", _OAuth_authorizationHeader).call(this, url, options, tokenPayload) }), | ||
@@ -91,3 +90,2 @@ method: options.method, | ||
} | ||
exports.default = OAuth; | ||
_OAuth_instances = new WeakSet(), _OAuth_authorizationHeader = function _OAuth_authorizationHeader(url, { method = 'GET', body = {}, qs, oauthHeaders }, tokenSet) { | ||
@@ -119,2 +117,3 @@ const authHeaders = Object.assign(Object.assign({ oauth_consumer_key: this.config.consumerKey, oauth_signature_method: this.config.signingMethod, oauth_timestamp: (0, oauthUtils_1.getTimestamp)(), oauth_nonce: (0, oauthUtils_1.getNonce)(), oauth_version: version }, tokenSet && { oauth_token: tokenSet.token }), oauthHeaders); | ||
}; | ||
exports.default = OAuth; | ||
//# sourceMappingURL=OAuth.js.map |
@@ -42,3 +42,3 @@ "use strict"; | ||
OAuthSigningMethod["Rsa"] = "RSA-SHA1"; | ||
})(OAuthSigningMethod = exports.OAuthSigningMethod || (exports.OAuthSigningMethod = {})); | ||
})(OAuthSigningMethod || (exports.OAuthSigningMethod = OAuthSigningMethod = {})); | ||
const oauthSign = (method, base, consumerSecret, tokenSecret) => { | ||
@@ -45,0 +45,0 @@ switch (method) { |
@@ -25,2 +25,5 @@ import { IOAuthCommon, IPopSession, IStoreSession } from '../OAuthCommon'; | ||
secretHeaderName?: string; | ||
responseType?: string; | ||
consentAdditionalParams?: Record<string, string>; | ||
addNonceToAuthorizeURL?: boolean; | ||
}); | ||
@@ -27,0 +30,0 @@ callback({ pop }: IPopSession, rawQuery: string): Promise<T>; |
@@ -44,4 +44,2 @@ "use strict"; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
// eslint-disable-next-line import/no-unresolved | ||
const node_fetch_1 = __importDefault(require("node-fetch")); | ||
const OAuth2Error_1 = __importDefault(require("./OAuth2Error")); | ||
@@ -62,4 +60,4 @@ const crypto_1 = __importStar(require("crypto")); | ||
const query = new url_1.URLSearchParams(rawQuery); | ||
const state = query.get('state'); | ||
if (state !== sessionState) | ||
const state = String(query.get('state')); | ||
if (!(0, lib_1.safeCompare)(state, sessionState)) | ||
throw new OAuth2Error_1.default('Invalid returning state'); | ||
@@ -84,4 +82,4 @@ if (query.get('error_code') | ||
const res = this.options.tokenRequestMethod === "GET" /* TokenRequestMethod.GET */ | ||
? yield (0, node_fetch_1.default)(`${this.config.tokenURL}?${body}`) | ||
: yield (0, node_fetch_1.default)(this.config.tokenURL, { | ||
? yield fetch(`${this.config.tokenURL}?${body}`) | ||
: yield fetch(this.config.tokenURL, { | ||
method: 'POST', | ||
@@ -109,2 +107,3 @@ headers: Object.assign({ 'Content-Type': 'application/x-www-form-urlencoded', Accept: 'application/json' }, this.options.secretHeaderName && { | ||
authenticate({ store }) { | ||
var _a; | ||
return __awaiter(this, void 0, void 0, function* () { | ||
@@ -121,3 +120,3 @@ const state = (0, crypto_1.randomUUID)(); | ||
return `${this.config.consentURL}?\ | ||
${new url_1.URLSearchParams(Object.assign(Object.assign(Object.assign({ [__classPrivateFieldGet(this, _OAuth2_instances, "a", _OAuth2_clientIDQueryName_get)]: this.config.clientID, redirect_uri: this.config.redirectUri, state }, this.config.scope && { scope: this.config.scope }), { response_type: 'code' }), this.options.enablePKCE && { | ||
${new url_1.URLSearchParams(Object.assign(Object.assign(Object.assign(Object.assign(Object.assign({ [__classPrivateFieldGet(this, _OAuth2_instances, "a", _OAuth2_clientIDQueryName_get)]: this.config.clientID, redirect_uri: this.config.redirectUri, state }, this.config.scope && { scope: this.config.scope }), { response_type: (_a = this.options.responseType) !== null && _a !== void 0 ? _a : 'code' }), this.options.enablePKCE && { | ||
code_challenge: crypto_1.default | ||
@@ -132,7 +131,8 @@ .createHash('sha256') | ||
code_challenge_method: 'S256' | ||
})).toString()}`; | ||
}), this.options.addNonceToAuthorizeURL && { | ||
nonce: (0, crypto_1.randomUUID)(), | ||
}), this.options.consentAdditionalParams)).toString()}`; | ||
}); | ||
} | ||
} | ||
exports.default = OAuth2; | ||
_OAuth2_instances = new WeakSet(), _OAuth2_clientIDQueryName_get = function _OAuth2_clientIDQueryName_get() { | ||
@@ -142,2 +142,3 @@ var _a; | ||
}; | ||
exports.default = OAuth2; | ||
//# sourceMappingURL=OAuth2.js.map |
@@ -16,3 +16,2 @@ "use strict"; | ||
const OAuth2_1 = __importDefault(require("../oauth2/OAuth2")); | ||
const node_fetch_1 = __importDefault(require("node-fetch")); | ||
const OAuthCommon_1 = require("../OAuthCommon"); | ||
@@ -30,3 +29,3 @@ const url_1 = require("url"); | ||
]) => __awaiter(void 0, void 0, void 0, function* () { | ||
const res = yield (0, node_fetch_1.default)(`https://graph.facebook.com/v16.0/me?${new url_1.URLSearchParams({ | ||
const res = yield fetch(`https://graph.facebook.com/v16.0/me?${new url_1.URLSearchParams({ | ||
access_token, | ||
@@ -33,0 +32,0 @@ fields: fields.join(',') |
@@ -16,3 +16,2 @@ "use strict"; | ||
const OAuth2_1 = __importDefault(require("../oauth2/OAuth2")); | ||
const node_fetch_1 = __importDefault(require("node-fetch")); | ||
const OAuthCommon_1 = require("../OAuthCommon"); | ||
@@ -22,3 +21,3 @@ const url_1 = require("url"); | ||
var _a, _b, _c, _d, _e, _f; | ||
const res = yield (0, node_fetch_1.default)(`https://api.foursquare.com/v2/users/self?${new url_1.URLSearchParams({ | ||
const res = yield fetch(`https://api.foursquare.com/v2/users/self?${new url_1.URLSearchParams({ | ||
oauth_token: access_token, | ||
@@ -25,0 +24,0 @@ v: '20200408' |
@@ -17,6 +17,5 @@ "use strict"; | ||
const OAuth2_1 = __importDefault(require("../oauth2/OAuth2")); | ||
const node_fetch_1 = __importDefault(require("node-fetch")); | ||
const OAuthCommon_1 = require("../OAuthCommon"); | ||
const fetchGithubProfile = ({ access_token }) => __awaiter(void 0, void 0, void 0, function* () { | ||
const res = yield (0, node_fetch_1.default)('https://api.github.com/user', { | ||
const res = yield fetch('https://api.github.com/user', { | ||
headers: { | ||
@@ -29,3 +28,3 @@ Authorization: `token ${access_token}`, | ||
throw new OAuthCommon_1.OAuthProfileError(yield res.text()); | ||
const emailRes = yield (0, node_fetch_1.default)('https://api.github.com/user/emails', { | ||
const emailRes = yield fetch('https://api.github.com/user/emails', { | ||
headers: { | ||
@@ -32,0 +31,0 @@ Authorization: `token ${access_token}`, |
@@ -16,3 +16,2 @@ "use strict"; | ||
const OAuth2_1 = __importDefault(require("../oauth2/OAuth2")); | ||
const node_fetch_1 = __importDefault(require("node-fetch")); | ||
const OAuthCommon_1 = require("../OAuthCommon"); | ||
@@ -29,3 +28,3 @@ const url_1 = require("url"); | ||
var _a; | ||
const res = yield (0, node_fetch_1.default)(`https://people.googleapis.com/v1/people/me?${new url_1.URLSearchParams({ | ||
const res = yield fetch(`https://people.googleapis.com/v1/people/me?${new url_1.URLSearchParams({ | ||
access_token, | ||
@@ -100,3 +99,3 @@ personFields: fields.join(',') | ||
return __awaiter(this, void 0, void 0, function* () { | ||
const response = yield (0, node_fetch_1.default)('https://oauth2.googleapis.com/token', { | ||
const response = yield fetch('https://oauth2.googleapis.com/token', { | ||
method: 'POST', | ||
@@ -103,0 +102,0 @@ headers: { |
@@ -16,3 +16,2 @@ "use strict"; | ||
const OAuth2_1 = __importDefault(require("../oauth2/OAuth2")); | ||
const node_fetch_1 = __importDefault(require("node-fetch")); | ||
const OAuthCommon_1 = require("../OAuthCommon"); | ||
@@ -27,3 +26,3 @@ const url_1 = require("url"); | ||
var _a, _b, _c, _d, _e, _f; | ||
const res = yield (0, node_fetch_1.default)(`https://graph.instagram.com/me?${new url_1.URLSearchParams({ | ||
const res = yield fetch(`https://graph.instagram.com/me?${new url_1.URLSearchParams({ | ||
access_token, | ||
@@ -43,3 +42,3 @@ fields: fields.join(',') | ||
if (profile.username) { | ||
const graphRes = yield (0, node_fetch_1.default)(`https://instagram.com/${profile.username}/?__a=1`); | ||
const graphRes = yield fetch(`https://instagram.com/${profile.username}/?__a=1`); | ||
if (graphRes.ok) { | ||
@@ -46,0 +45,0 @@ graphProfile = yield graphRes.json(); |
@@ -16,3 +16,2 @@ "use strict"; | ||
const OAuth2_1 = __importDefault(require("../oauth2/OAuth2")); | ||
const node_fetch_1 = __importDefault(require("node-fetch")); | ||
const OAuthCommon_1 = require("../OAuthCommon"); | ||
@@ -42,3 +41,3 @@ const url_1 = require("url"); | ||
if (!ignoreEmail && id_token) { | ||
const res = yield (0, node_fetch_1.default)('https://api.line.me/oauth2/v2.1/verify', { | ||
const res = yield fetch('https://api.line.me/oauth2/v2.1/verify', { | ||
method: 'POST', | ||
@@ -58,3 +57,3 @@ body: new url_1.URLSearchParams({ | ||
} | ||
const res = yield (0, node_fetch_1.default)('https://api.line.me/v2/profile', { | ||
const res = yield fetch('https://api.line.me/v2/profile', { | ||
headers: { | ||
@@ -83,3 +82,3 @@ Authorization: `Bearer ${access_token}` | ||
return __awaiter(this, void 0, void 0, function* () { | ||
const response = yield (0, node_fetch_1.default)('https://api.line.me/oauth2/v2.1/token', { | ||
const response = yield fetch('https://api.line.me/oauth2/v2.1/token', { | ||
method: 'POST', | ||
@@ -86,0 +85,0 @@ headers: { |
@@ -16,6 +16,5 @@ "use strict"; | ||
const OAuth2_1 = __importDefault(require("../oauth2/OAuth2")); | ||
const node_fetch_1 = __importDefault(require("node-fetch")); | ||
const OAuthCommon_1 = require("../OAuthCommon"); | ||
const fetchLinkedInProfile = ({ access_token }) => __awaiter(void 0, void 0, void 0, function* () { | ||
const res = yield (0, node_fetch_1.default)(`https://api.linkedin.com/v2/me?projection=(${[ | ||
const res = yield fetch(`https://api.linkedin.com/v2/me?projection=(${[ | ||
'id', | ||
@@ -22,0 +21,0 @@ 'profilePicture(displayImage~:playableStreams)', |
@@ -16,6 +16,5 @@ "use strict"; | ||
const OAuth2_1 = __importDefault(require("../oauth2/OAuth2")); | ||
const node_fetch_1 = __importDefault(require("node-fetch")); | ||
const OAuthCommon_1 = require("../OAuthCommon"); | ||
const fetchPinterestProfile = ({ data: { access_token } }) => __awaiter(void 0, void 0, void 0, function* () { | ||
const res = yield (0, node_fetch_1.default)('https://api.pinterest.com/v3/users/me', { | ||
const res = yield fetch('https://api.pinterest.com/v3/users/me', { | ||
headers: { | ||
@@ -22,0 +21,0 @@ Authorization: `Bearer ${access_token}` |
@@ -16,3 +16,2 @@ "use strict"; | ||
const OAuth2_1 = __importDefault(require("../oauth2/OAuth2")); | ||
const node_fetch_1 = __importDefault(require("node-fetch")); | ||
const OAuthCommon_1 = require("../OAuthCommon"); | ||
@@ -28,3 +27,3 @@ const url_1 = require("url"); | ||
var _a, _b; | ||
const res = yield (0, node_fetch_1.default)(`https://graph.zalo.me/v2.0/me?${new url_1.URLSearchParams({ | ||
const res = yield fetch(`https://graph.zalo.me/v2.0/me?${new url_1.URLSearchParams({ | ||
access_token, | ||
@@ -66,3 +65,3 @@ fields: fields.join(',') | ||
return __awaiter(this, void 0, void 0, function* () { | ||
const response = yield (0, node_fetch_1.default)('https://oauth.zaloapp.com/v4/access_token', { | ||
const response = yield fetch('https://oauth.zaloapp.com/v4/access_token', { | ||
method: 'POST', | ||
@@ -69,0 +68,0 @@ headers: { |
{ | ||
"name": "express-authenticators", | ||
"version": "0.1.5", | ||
"description": "Third party authenticators in nodejs. Support various providers. Zero heavy dependencies.", | ||
"version": "0.2.0-experiiment-1", | ||
"description": "Third party authenticators in nodejs. Support various providers. Almost zero dependencies.", | ||
"main": "lib/index.js", | ||
@@ -25,3 +25,4 @@ "repository": "github:tranvansang/express-authenticators", | ||
"oauth", | ||
"oauth2" | ||
"oauth2", | ||
"apple" | ||
], | ||
@@ -41,20 +42,17 @@ "files": [ | ||
"dependencies": { | ||
"node-fetch": "^2.6.5", | ||
"r3986": "^0.0.3" | ||
}, | ||
"devDependencies": { | ||
"@babel/core": "^7.21.8", | ||
"@babel/plugin-proposal-class-properties": "^7.18.6", | ||
"@babel/plugin-syntax-object-rest-spread": "^7.8.3", | ||
"@babel/plugin-transform-runtime": "^7.21.4", | ||
"@babel/preset-env": "^7.21.5", | ||
"@babel/preset-typescript": "^7.21.5", | ||
"@babel/runtime": "^7.21.5", | ||
"@types/jest": "^29.5.1", | ||
"@types/node": "^20.2.3", | ||
"@typescript-eslint/eslint-plugin": "^5.59.7", | ||
"@typescript-eslint/parser": "^5.59.7", | ||
"@babel/core": "^7.22.5", | ||
"@babel/plugin-transform-runtime": "^7.22.5", | ||
"@babel/preset-env": "^7.22.5", | ||
"@babel/preset-typescript": "^7.22.5", | ||
"@babel/runtime": "^7.22.5", | ||
"@types/jest": "^29.5.2", | ||
"@types/node": "^20.3.0", | ||
"@typescript-eslint/eslint-plugin": "^5.59.9", | ||
"@typescript-eslint/parser": "^5.59.9", | ||
"babel-eslint": "^10.1.0", | ||
"babel-jest": "^29.5.0", | ||
"eslint": "^8.41.0", | ||
"eslint": "^8.42.0", | ||
"eslint-config-airbnb-base": "^15.0.0", | ||
@@ -65,4 +63,4 @@ "eslint-plugin-babel": "^5.3.1", | ||
"jest": "^29.5.0", | ||
"typescript": "^5.0.4" | ||
"typescript": "^5.1.3" | ||
} | ||
} |
@@ -9,7 +9,6 @@ # Express Authenticators [![Build Status](https://travis-ci.org/tranvansang/express-authenticators.svg?branch=master)](https://travis-ci.org/tranvansang/express-authenticators) | ||
- Pre-configured for popular providers: Google, Facebook, Foursquare, Github, Twitter, LinkedIn, LINE, Pinterest, | ||
Tumblr, Instagram. | ||
- Pre-configured for popular providers: Apple, Google, Facebook, Foursquare, Github, Twitter, LinkedIn, LINE, Pinterest, Tumblr, Instagram. | ||
- Pre-configured for popular scopes: email, profile, etc. with account fetching for basic user information. | ||
- The original OAuth/OAuth2 classes are available for customized providers. | ||
- The only dependencies are `r3986` and `node-fetch`. | ||
- The only dependencies are `r3986`. | ||
- Modern NodeJS. Although, it requires NodeJS >= v14.17.0 to use the `randomUUID()` function. | ||
@@ -25,4 +24,8 @@ - Strongly typed with TypeScript. | ||
Note: before `v0.1.0`, this package was for ExpressJS only, hence its name is `express-authenticators`. | ||
## Requirement | ||
- `fetch` polyfilled. | ||
- NodeJS >= v14.17.0. | ||
(before `v0.1.0`, this package was for ExpressJS only, hence its name is `express-authenticators`) | ||
## Sample code in ExpressJS | ||
@@ -33,2 +36,3 @@ | ||
const { | ||
AppleAuthenticator, | ||
FacebookAuthenticator, | ||
@@ -77,3 +81,3 @@ FoursquareAuthenticator, | ||
) | ||
app.get( | ||
app.get( // for AppleAuthenticator, must use POST method instead | ||
`/auth/facebook/callback`, | ||
@@ -84,5 +88,5 @@ async (req, res, next) => { | ||
req.session.oauthFacebook, | ||
new URL(`https://example.com${req.url}`).search | ||
new URL(`https://example.com${req.url}`).search // for AppleAuthenticator, use req.body instead | ||
) | ||
const profile = await facebookAuth.fetchProfile(payload) | ||
const profile = await facebookAuth.fetchProfile(payload) // not supported by AppleAuthenticator | ||
console.log('got profile', profile) | ||
@@ -99,4 +103,2 @@ res.send(JSON.stringify(profile)) | ||
Note that NodeJS >= v14.17.0 is required. | ||
## Exported classes | ||
@@ -108,2 +110,3 @@ | ||
- Pre-configured providers that inherit `OAuth2`: | ||
- `AppleAuthenticator` | ||
- `FacebookAuthenticator` | ||
@@ -126,3 +129,3 @@ - `FoursquareAuthenticator` | ||
clientID: string | ||
clientSecret: string | ||
clientSecret: string // not required for AppleAuthenticator | ||
redirectUri: string | ||
@@ -154,3 +157,3 @@ } | ||
- `fetchProfile(tokenPayload): Promise<IOAuthProfile>`: takes the token payload returned from the `callback()` method | ||
- `fetchProfile(tokenPayload): Promise<IOAuthProfile>` (not available with AppleAuthenticator): takes the token payload returned from the `callback()` method | ||
and returns the profile data. Although each provider returns different data, they are all pre-configured in this | ||
@@ -157,0 +160,0 @@ library to return the `IOAuthProfile` described below. |
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
Network access
Supply chain riskThis module accesses the network.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
122537
1
18
65
1727
253
18
- Removednode-fetch@^2.6.5
- Removednode-fetch@2.7.0(transitive)
- Removedtr46@0.0.3(transitive)
- Removedwebidl-conversions@3.0.1(transitive)
- Removedwhatwg-url@5.0.0(transitive)