public async authenticateCodeWithPkce()

in src/services/oauthService.ts [181:238]


    public async authenticateCodeWithPkce(backendUrl: string, authorizationServer: AuthorizationServer): Promise<string> {
        const redirectUri = `${backendUrl}/signin-oauth/code-pkce/callback/${authorizationServer.name}`;
        const codeVerifier = this.generateRandomString(64);
        const challengeMethod = crypto.subtle ? "S256" : "plain"

        const codeChallenge = challengeMethod === "S256"
            ? await this.generateCodeChallenge(codeVerifier)
            : codeVerifier

        sessionStorage.setItem("code_verifier", codeVerifier);

        const args = new URLSearchParams({
            response_type: "code",
            client_id: authorizationServer.clientId,
            code_challenge_method: challengeMethod,
            code_challenge: codeChallenge,
            redirect_uri: redirectUri.toLowerCase(),
            scope: authorizationServer.scopes.join(" ")
        });

        const listener = async (event: MessageEvent): Promise<string> => {
            const authorizationCode = event.data["code"];

            if (!authorizationCode) {
                alert("Unable to authenticate due to internal error.");
                return;
            }

            const body = new URLSearchParams({
                client_id: authorizationServer.clientId,
                code_verifier: sessionStorage.getItem("code_verifier"),
                grant_type: GrantTypes.authorizationCode,
                redirect_uri: redirectUri,
                code: authorizationCode
            });

            const response = await this.httpClient.send<OAuthTokenResponse>({
                url: authorizationServer.tokenEndpoint,
                method: HttpMethod.post,
                headers: [{ name: KnownHttpHeaders.ContentType, value: KnownMimeTypes.UrlEncodedForm }],
                body: body.toString()
            });

            if (response.statusCode === 400) {
                const error = response.toText();
                alert(error);
                return;
            }

            const tokenResponse = response.toObject();
            const accessToken = tokenResponse.access_token;
            const accessTokenType = tokenResponse.token_type;

            return `${Utils.toTitleCase(accessTokenType)} ${accessToken}`;
        };

        return this.openAuthPopup(`${authorizationServer.authorizationEndpoint}?${args}`, listener);
    }