@itwin/insights-client
Version:
Insights client for the iTwin platform
151 lines • 7.41 kB
JavaScript
;
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
return c > 3 && r && Object.defineProperty(target, key, r), r;
};
var __param = (this && this.__param) || function (paramIndex, decorator) {
return function (target, key) { decorator(target, key, paramIndex); }
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.TestAuthorizationClient = void 0;
const url_1 = require("url");
const inversify_1 = require("inversify");
const puppeteer = require("puppeteer");
const CommonTestUtils_1 = require("../../CommonTestUtils");
const TestAuthorizationClientConfigImpl_1 = require("./TestAuthorizationClientConfigImpl");
let TestAuthorizationClient = class TestAuthorizationClient {
constructor(_authConfig) {
this._authConfig = _authConfig;
// cspell:disable-next-line
this._pageLoadedEvent = "networkidle2";
this._consentPageTitle = "Permissions";
this._pageElementIds = {
fields: {
email: "#identifierInput",
password: "#password",
},
buttons: {
next: "#sign-in-button",
signIn: "#sign-in-button",
consent: ".ping.button.normal.allow",
},
};
}
async getAccessToken(testUserCredentials) {
const browserLaunchOptions = {
headless: true,
defaultViewport: {
width: 800,
height: 1200,
},
};
const browser = await puppeteer.launch(browserLaunchOptions);
const browserPage = await browser.newPage();
const authorizationCodePromise = this.interceptRedirectAndGetAuthorizationCode(browserPage);
await browserPage.goto(this.getAuthorizationUrl(testUserCredentials), { waitUntil: this._pageLoadedEvent });
await this.fillCredentials(browserPage, testUserCredentials);
await this.consentIfNeeded(browserPage);
const accessToken = await this.exchangeAuthorizationCodeForAccessToken(await authorizationCodePromise);
await browser.close();
return accessToken;
}
getAuthorizationUrl(testUserCredentials) {
return `${this._authConfig.authority}/connect/authorize?` +
`client_id=${encodeURIComponent(this._authConfig.clientId)}&` +
`scope=${encodeURIComponent(testUserCredentials.scopes)}&` +
"response_type=code&" +
`redirect_uri=${encodeURIComponent(this._authConfig.redirectUrl)}`;
}
async fillCredentials(browserPage, testUserCredentials) {
const emailField = await this.captureElement(browserPage, this._pageElementIds.fields.email);
await emailField.type(testUserCredentials.email);
const nextButton = await this.captureElement(browserPage, this._pageElementIds.buttons.next);
await nextButton.click();
const passwordField = await this.captureElement(browserPage, this._pageElementIds.fields.password);
await passwordField.type(testUserCredentials.password);
const signInButton = await this.captureElement(browserPage, this._pageElementIds.buttons.signIn);
await Promise.all([
signInButton.click(),
browserPage.waitForNavigation({ waitUntil: this._pageLoadedEvent }),
]);
}
async consentIfNeeded(browserPage) {
const isConsentPage = await browserPage.title() === this._consentPageTitle;
if (!isConsentPage) {
return;
}
const consentButton = await this.captureElement(browserPage, this._pageElementIds.buttons.consent);
await Promise.all([
consentButton.click(),
browserPage.waitForNavigation({ waitUntil: this._pageLoadedEvent }),
]);
}
async exchangeAuthorizationCodeForAccessToken(authorizationCode) {
const requestUrl = `${this._authConfig.authority}/connect/token`;
const requestBody = new url_1.URLSearchParams({
// eslint-disable-next-line @typescript-eslint/naming-convention
grant_type: "authorization_code",
code: authorizationCode,
// eslint-disable-next-line @typescript-eslint/naming-convention
redirect_uri: this._authConfig.redirectUrl,
});
// eslint-disable-next-line @typescript-eslint/naming-convention
const encodedClientCredentials = Buffer.from(`${encodeURIComponent(this._authConfig.clientId)}:${encodeURIComponent(this._authConfig.clientSecret)}`).toString("base64");
const requestConfig = {
method: "POST",
headers: {
// eslint-disable-next-line @typescript-eslint/naming-convention
"Content-Type": "application/x-www-form-urlencoded",
// eslint-disable-next-line @typescript-eslint/naming-convention
"Authorization": `Basic ${encodedClientCredentials}`,
},
body: requestBody,
};
const response = await fetch(requestUrl, requestConfig);
const data = await response.json();
return data.access_token;
}
async interceptRedirectAndGetAuthorizationCode(browserPage) {
await browserPage.setRequestInterception(true);
return new Promise((resolve) => {
browserPage.on("request", async (interceptedRequest) => {
const currentRequestUrl = interceptedRequest.url();
if (!currentRequestUrl.startsWith(this._authConfig.redirectUrl)) {
await interceptedRequest.continue();
}
else {
await this.respondSuccess(interceptedRequest);
resolve(this.getCodeFromUrl(currentRequestUrl));
}
});
});
}
async respondSuccess(request) {
await request.respond({
status: 200,
contentType: "text/html",
body: "OK",
});
}
getCodeFromUrl(redirectUrl) {
// eslint-disable-next-line deprecation/deprecation
const urlQuery = (0, url_1.parse)(redirectUrl, true).query;
if (!urlQuery.code)
throw new CommonTestUtils_1.TestSetupError("Sign in failed: could not parse code from url.");
return urlQuery.code.toString();
}
async captureElement(browserPage, selector) {
const element = await browserPage.waitForSelector(selector);
if (!element)
throw new CommonTestUtils_1.TestSetupError(`Sign in failed: could not find element with selector '${selector}'.`);
return element;
}
};
exports.TestAuthorizationClient = TestAuthorizationClient;
exports.TestAuthorizationClient = TestAuthorizationClient = __decorate([
(0, inversify_1.injectable)(),
__param(0, (0, inversify_1.inject)(TestAuthorizationClientConfigImpl_1.TestAuthorizationClientConfig))
], TestAuthorizationClient);
//# sourceMappingURL=TestAuthorizationClient.js.map