UNPKG

@adonisjs/ally

Version:

Social authentication provider for AdonisJS

170 lines (168 loc) 4.33 kB
import { E_OAUTH_MISSING_CODE, E_OAUTH_STATE_MISMATCH, RedirectRequest } from "./chunk-N72DEJC2.js"; // src/abstract_drivers/oauth1.ts import { Exception } from "@poppinss/utils"; import { Oauth1Client } from "@poppinss/oauth-client/oauth1"; var Oauth1Driver = class extends Oauth1Client { constructor(ctx, config) { super(config); this.ctx = ctx; this.config = config; } /** * Oauth client version */ version = "oauth1"; /** * The value of "oauth_token" and "oauth_secret" from the cookies */ oauthTokenCookieValue; oauthSecretCookieValue; /** * The cookie name for storing the secret */ get oauthSecretCookieName() { return `${this.oauthTokenCookieName}_secret`; } /** * The Oauth1Client will use the instance returned from this method to * build the redirect url */ urlBuilder(url) { return new RedirectRequest(url, this.scopeParamName, this.scopesSeparator); } /** * Loads the value of state from the cookie and removes it right * away. We read the cookie value and clear it during the * current request lifecycle. * * ::::: * NOTE * ::::: * * This child class must call this method inside the constructor. */ loadState() { this.oauthTokenCookieValue = this.ctx.request.encryptedCookie(this.oauthTokenCookieName); this.oauthSecretCookieValue = this.ctx.request.encryptedCookie(this.oauthSecretCookieName); this.ctx.response.clearCookie(this.oauthTokenCookieName); this.ctx.response.clearCookie(this.oauthSecretCookieName); } /** * Persists the token (aka state) inside the cookie */ #persistToken(token) { this.ctx.response.encryptedCookie(this.oauthTokenCookieName, token, { sameSite: false, httpOnly: true }); } /** * Persists the secret inside the cookie */ #persistSecret(secret) { this.ctx.response.encryptedCookie(this.oauthSecretCookieName, secret, { sameSite: false, httpOnly: true }); } /** * Perform stateless authentication. Only applicable for Oauth1 client */ stateless() { throw new Exception("OAuth1 does not support stateless authorization"); } /** * Returns the redirect URL for the request. */ async redirectUrl(callback) { return this.getRedirectUrl(callback); } /** * Redirect user for authorization. */ async redirect(callback) { const { token, secret } = await this.getRequestToken(); this.#persistToken(token); this.#persistSecret(secret); const url = await this.redirectUrl((request) => { request.param(this.oauthTokenParamName, token); if (typeof callback === "function") { callback(request); } }); this.ctx.response.redirect(url); } /** * Find if there is a state mismatch */ stateMisMatch() { return this.oauthTokenCookieValue !== this.ctx.request.input(this.oauthTokenParamName); } /** * Find if there is an error post redirect */ hasError() { return !!this.getError(); } /** * Get the post redirect error */ getError() { const error = this.ctx.request.input(this.errorParamName); if (error) { return error; } if (!this.hasCode()) { return "unknown_error"; } return null; } /** * Returns the "oauth_verifier" token */ getCode() { return this.ctx.request.input(this.oauthTokenVerifierName, null); } /** * Find it the code exists */ hasCode() { return !!this.getCode(); } /** * Get access token */ async accessToken(callback) { if (this.hasError()) { throw new E_OAUTH_MISSING_CODE([this.oauthTokenVerifierName]); } if (this.stateMisMatch()) { throw new E_OAUTH_STATE_MISMATCH(); } return this.getAccessToken( { token: this.oauthTokenCookieValue, secret: this.oauthSecretCookieValue }, (request) => { request.oauth1Param(this.oauthTokenVerifierName, this.getCode()); if (typeof callback === "function") { callback(request); } } ); } /** * Not applicable with Oauth1 */ async userFromToken() { throw new Exception( '"userFromToken" is not available with Oauth1. Use "userFromTokenAndSecret" instead' ); } }; export { Oauth1Driver }; //# sourceMappingURL=chunk-VHORNQLN.js.map