remix-auth-okta
Version: 
  # OktaStrategy
115 lines (114 loc) • 4.22 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", { value: true });
exports.OktaStrategy = void 0;
const remix_auth_oauth2_1 = require("remix-auth-oauth2");
class OktaStrategy extends remix_auth_oauth2_1.OAuth2Strategy {
    constructor({ issuer, scope = "openid profile email", clientID, clientSecret, callbackURL, ...rest }, verify) {
        super({
            authorizationURL: `${issuer}/v1/authorize`,
            tokenURL: `${issuer}/v1/token`,
            clientID,
            clientSecret,
            callbackURL,
        }, verify);
        this.name = "okta";
        this.sessionToken = "";
        this.scope = scope;
        this.userInfoURL = `${issuer}/v1/userinfo`;
        this.authenticationURL = `${issuer}/api/v1/authn`;
        this.withCustomLoginForm = !!rest.withCustomLoginForm;
        this.authenticationURL = rest.withCustomLoginForm
            ? `${rest.oktaDomain}/api/v1/authn`
            : "";
    }
    async authenticate(request, sessionStorage, options) {
        var _a;
        if (!this.withCustomLoginForm) {
            return super.authenticate(request, sessionStorage, options);
        }
        let session = await sessionStorage.getSession(request.headers.get("Cookie"));
        let user = (_a = session.get(options.sessionKey)) !== null && _a !== void 0 ? _a : null;
        if (user) {
            return this.success(user, request.clone(), sessionStorage, options);
        }
        const url = new URL(request.url);
        const callbackUrl = this.getCallbackURLFrom(url);
        if (url.pathname !== callbackUrl.pathname) {
            const form = await request.formData();
            const email = form.get("email");
            const password = form.get("password");
            if (!email || !password) {
                throw new Response(JSON.stringify({
                    message: "Bad request, missing email and password.",
                }), {
                    headers: {
                        "Content-Type": "application/json; charset=utf-8",
                    },
                    status: 400,
                });
            }
            this.sessionToken = await this.getSessionTokenWith(email.toString(), password.toString());
        }
        return super.authenticate(request, sessionStorage, options);
    }
    getCallbackURLFrom(url) {
        if (this.callbackURL.startsWith("http:") ||
            this.callbackURL.startsWith("https:")) {
            return new URL(this.callbackURL);
        }
        if (this.callbackURL.startsWith("/")) {
            return new URL(this.callbackURL, url);
        }
        return new URL(`${url.protocol}//${this.callbackURL}`);
    }
    async getSessionTokenWith(email, password) {
        let response = await fetch(this.authenticationURL, {
            method: "POST",
            headers: {
                "Content-Type": "application/json",
            },
            body: JSON.stringify({
                username: email,
                password,
            }),
        });
        if (!response.ok) {
            try {
                let body = await response.text();
                throw new Error(body);
            }
            catch (error) {
                throw error;
            }
        }
        const data = await response.json();
        return data.sessionToken;
    }
    authorizationParams() {
        return new URLSearchParams({
            scope: this.scope,
            sessionToken: this.sessionToken,
        });
    }
    async userProfile(accessToken) {
        var _a;
        const response = await fetch(this.userInfoURL, {
            headers: {
                Authorization: `Bearer ${accessToken}`,
            },
        });
        const profile = await response.json();
        return {
            provider: "okta",
            id: profile.sub,
            name: {
                familyName: profile.family_name,
                givenName: profile.given_name,
                middleName: profile.middle_name,
            },
            displayName: (_a = profile.name) !== null && _a !== void 0 ? _a : profile.preferred_username,
            email: profile.email,
        };
    }
}
exports.OktaStrategy = OktaStrategy;