UNPKG

easy-social-auth

Version:

A flexible, standalone package for social authentication using Google, Facebook & Twitter

266 lines (265 loc) 12.4 kB
"use strict"; var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } return new (P || (P = Promise))(function (resolve, reject) { function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } step((generator = generator.apply(thisArg, _arguments || [])).next()); }); }; var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; Object.defineProperty(exports, "__esModule", { value: true }); exports.TwitterStrategy = void 0; const axios_1 = __importDefault(require("axios")); const easy_social_auth_strategy_1 = require("./easy-social-auth.strategy"); const grant_type_enum_1 = require("../enums/grant-type.enum"); const crypto_1 = __importDefault(require("crypto")); const token_type_enum_1 = require("../enums/token-type.enum"); class TwitterStrategy extends easy_social_auth_strategy_1.AuthStrategy { constructor(config) { super(config.clientId, config.clientSecret, config.userInfoEndpoint, config.tokenEndpoint, config.authUrl); this.config = config; } // ======= OAuth 2.0 Methods (Unchanged) ======= getUserData(accessToken) { return __awaiter(this, void 0, void 0, function* () { var _a, _b; try { const { data } = yield axios_1.default.get(this.userInfoEndpoint, { headers: { Authorization: `Bearer ${accessToken}` }, }); if (data) return { status: true, data: data, }; return { status: false, error: "Unable to retrieve user data" }; } catch (error) { return { status: false, error: ((_b = (_a = error.response) === null || _a === void 0 ? void 0 : _a.data) === null || _b === void 0 ? void 0 : _b.error_description) || error.message, }; } }); } exchangeCodeForToken(code_1, redirectUri_1) { return __awaiter(this, arguments, void 0, function* (code, redirectUri, additionalParams = {}, clientType) { var _a, _b; try { let headers = { "Content-Type": "application/x-www-form-urlencoded", }; let params = { grant_type: grant_type_enum_1.GrantType.AUTHORIZATION_CODE, code: code, redirect_uri: redirectUri, code_verifier: (additionalParams === null || additionalParams === void 0 ? void 0 : additionalParams.code_verifier) || "", }; if (clientType === "CONFIDENTIAL") { if (!this.clientId || !this.clientSecret) { throw new Error("Client ID or Client Secret is missing for confidential clients."); } headers["Authorization"] = `Basic ${Buffer.from(`${this.clientId}:${this.clientSecret}`).toString("base64")}`; } else { params["client_id"] = this.clientId; } const body = new URLSearchParams(params).toString(); const { data } = yield axios_1.default.post(this.tokenEndpoint, body, { headers }); return { status: true, data: data, }; } catch (error) { return { status: false, error: ((_b = (_a = error.response) === null || _a === void 0 ? void 0 : _a.data) === null || _b === void 0 ? void 0 : _b.error_description) || error.message, }; } }); } refreshAccessToken(refreshToken) { return __awaiter(this, void 0, void 0, function* () { var _a, _b; try { const { data } = yield axios_1.default.post(this.tokenEndpoint, null, { headers: { Authorization: `Basic ${Buffer.from(`${this.clientId}:${this.clientSecret}`).toString("base64")}`, "Content-Type": "application/x-www-form-urlencoded", }, params: { grant_type: grant_type_enum_1.GrantType.REFRESH_TOKEN, refresh_token: refreshToken, }, }); return { status: true, data: data, }; } catch (error) { return { status: false, error: ((_b = (_a = error.response) === null || _a === void 0 ? void 0 : _a.data) === null || _b === void 0 ? void 0 : _b.error_description) || error.message, }; } }); } requestAppToken(scope, clientType) { return __awaiter(this, void 0, void 0, function* () { var _a, _b; try { const { data } = yield axios_1.default.post(this.tokenEndpoint, null, { headers: { Authorization: `Basic ${Buffer.from(`${this.clientId}:${this.clientSecret}`).toString("base64")}`, "Content-Type": "application/x-www-form-urlencoded;charset=UTF-8", }, params: { grant_type: grant_type_enum_1.GrantType.CLIENT_CREDENTIALS, client_secret: this.clientSecret, client_type: clientType !== null && clientType !== void 0 ? clientType : "third_party_app", scope: scope, }, }); return { status: true, data: data }; } catch (error) { return { status: false, error: ((_b = (_a = error.response) === null || _a === void 0 ? void 0 : _a.data) === null || _b === void 0 ? void 0 : _b.error_description) || error.message, }; } }); } revokeAccessToken(token, token_type_hint) { return __awaiter(this, void 0, void 0, function* () { var _a, _b, _c; try { const { data } = yield axios_1.default.post((_a = this.config.revokeTokenUrl) !== null && _a !== void 0 ? _a : "https://api.x.com/2/oauth2/revoke", null, { headers: { Authorization: `Basic ${Buffer.from(`${this.clientId}:${this.clientSecret}`).toString("base64")}`, "Content-Type": "application/x-www-form-urlencoded;charset=UTF-8", }, params: { token: token, token_type_hint: token_type_hint !== null && token_type_hint !== void 0 ? token_type_hint : token_type_enum_1.TokenTypeEnum.ACCESS_TOKEN, }, }); return { status: true, data: data }; } catch (error) { return { status: false, error: ((_c = (_b = error.response) === null || _b === void 0 ? void 0 : _b.data) === null || _c === void 0 ? void 0 : _c.error_description) || error.message, }; } }); } // ======= New OAuth 1.0a Methods ======= getRequestOAuth_1_0_Token(callbackUrl) { return __awaiter(this, void 0, void 0, function* () { var _a; try { const params = { oauth_callback: callbackUrl, oauth_consumer_key: this.config.apiKey, oauth_nonce: this.generateNonce(), oauth_signature_method: "HMAC-SHA1", oauth_timestamp: this.generateTimestamp(), oauth_version: "1.0", }; const signature = this.generateSignature("POST", this.config.OAuth_1_0_RequestTokenUrl, params); const response = yield axios_1.default.post(this.config.OAuth_1_0_RequestTokenUrl, null, { headers: { Authorization: this.buildAuthHeader(Object.assign(Object.assign({}, params), { oauth_signature: signature })), "Content-Type": "application/x-www-form-urlencoded", }, }); const data = new URLSearchParams(response.data); return { status: true, data: { oauth_token: data.get("oauth_token"), oauth_token_secret: data.get("oauth_token_secret"), }, }; } catch (error) { return { status: false, error: ((_a = error.response) === null || _a === void 0 ? void 0 : _a.data) || error.message, }; } }); } getAuthorizationUrl(oauthToken) { return `${this.config.OAuth_1_0_AuthUrl}?oauth_token=${oauthToken}`; } getOAuth_1_0_AccessToken(oauthToken, oauthVerifier) { return __awaiter(this, void 0, void 0, function* () { var _a; try { const params = { oauth_consumer_key: this.clientId, oauth_token: oauthToken, oauth_nonce: this.generateNonce(), oauth_signature_method: "HMAC-SHA1", oauth_timestamp: this.generateTimestamp(), oauth_verifier: oauthVerifier, oauth_version: "1.0", }; const signature = this.generateSignature("POST", this.config.OAuth_1_0_AccessTokenUrl, params); const response = yield axios_1.default.post(this.config.OAuth_1_0_AccessTokenUrl, null, { headers: { Authorization: this.buildAuthHeader(Object.assign(Object.assign({}, params), { oauth_signature: signature })), "Content-Type": "application/x-www-form-urlencoded", }, }); const data = new URLSearchParams(response.data); return { status: true, data: { oauth_token: data.get("oauth_token"), oauth_token_secret: data.get("oauth_token_secret"), }, }; } catch (error) { return { status: false, error: ((_a = error.response) === null || _a === void 0 ? void 0 : _a.data) || error.message, }; } }); } buildAuthHeader(params) { return ("OAuth " + Object.entries(params) .map(([key, value]) => `${encodeURIComponent(key)}="${encodeURIComponent(value)}"`) .join(", ")); } generateNonce() { return Math.random().toString(36).substring(2, 15); } generateTimestamp() { return Math.floor(Date.now() / 1000).toString(); } generateSignature(method, url, params) { const sortedParams = Object.keys(params) .sort((a, b) => a.localeCompare(b)) .map((key) => `${encodeURIComponent(key)}=${encodeURIComponent(params[key])}`) .join("&"); const baseString = `${method.toUpperCase()}&${encodeURIComponent(url)}&${encodeURIComponent(sortedParams)}`; const signingKey = `${encodeURIComponent(this.config.consumerSecret)}&`; return crypto_1.default .createHmac("sha1", signingKey) .update(baseString) .digest("base64"); } } exports.TwitterStrategy = TwitterStrategy;