2019-07-11 23:00:24 +08:00
|
|
|
/*
|
|
|
|
Copyright 2019 The Matrix.org Foundation C.I.C.
|
|
|
|
|
|
|
|
Licensed under the Apache License, Version 2.0 (the "License");
|
|
|
|
you may not use this file except in compliance with the License.
|
|
|
|
You may obtain a copy of the License at
|
|
|
|
|
|
|
|
http://www.apache.org/licenses/LICENSE-2.0
|
|
|
|
|
|
|
|
Unless required by applicable law or agreed to in writing, software
|
|
|
|
distributed under the License is distributed on an "AS IS" BASIS,
|
|
|
|
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
|
|
See the License for the specific language governing permissions and
|
|
|
|
limitations under the License.
|
|
|
|
*/
|
|
|
|
|
2022-10-13 01:59:07 +08:00
|
|
|
import { mocked } from "jest-mock";
|
|
|
|
import fetchMock from "fetch-mock-jest";
|
|
|
|
|
2019-07-11 23:00:24 +08:00
|
|
|
import ScalarAuthClient from '../src/ScalarAuthClient';
|
|
|
|
import { stubClient } from './test-utils';
|
2022-10-13 01:59:07 +08:00
|
|
|
import SdkConfig from "../src/SdkConfig";
|
|
|
|
import { WidgetType } from "../src/widgets/WidgetType";
|
2019-07-11 23:00:24 +08:00
|
|
|
|
|
|
|
describe('ScalarAuthClient', function() {
|
2022-10-13 01:59:07 +08:00
|
|
|
const apiUrl = 'https://test.com/api';
|
|
|
|
const uiUrl = 'https:/test.com/app';
|
|
|
|
const tokenObject = {
|
|
|
|
access_token: "token",
|
|
|
|
token_type: "Bearer",
|
|
|
|
matrix_server_name: "localhost",
|
|
|
|
expires_in: 999,
|
|
|
|
};
|
|
|
|
|
|
|
|
let client;
|
2019-07-11 23:00:24 +08:00
|
|
|
beforeEach(function() {
|
2022-10-13 01:59:07 +08:00
|
|
|
jest.clearAllMocks();
|
|
|
|
client = stubClient();
|
2019-07-11 23:00:24 +08:00
|
|
|
});
|
|
|
|
|
|
|
|
it('should request a new token if the old one fails', async function() {
|
2022-10-13 01:59:07 +08:00
|
|
|
const sac = new ScalarAuthClient(apiUrl + 0, uiUrl);
|
2019-07-11 23:00:24 +08:00
|
|
|
|
2022-10-13 01:59:07 +08:00
|
|
|
fetchMock.get("https://test.com/api0/account?scalar_token=brokentoken&v=1.1", {
|
|
|
|
body: { message: "Invalid token" },
|
2019-07-11 23:00:24 +08:00
|
|
|
});
|
|
|
|
|
2022-10-13 01:59:07 +08:00
|
|
|
fetchMock.get("https://test.com/api0/account?scalar_token=wokentoken&v=1.1", {
|
|
|
|
body: { user_id: client.getUserId() },
|
|
|
|
});
|
|
|
|
|
|
|
|
client.getOpenIdToken = jest.fn().mockResolvedValue(tokenObject);
|
2019-07-11 23:00:24 +08:00
|
|
|
|
2019-12-16 19:12:48 +08:00
|
|
|
sac.exchangeForScalarToken = jest.fn((arg) => {
|
2022-10-13 01:59:07 +08:00
|
|
|
if (arg === tokenObject) return Promise.resolve("wokentoken");
|
2019-12-16 19:12:48 +08:00
|
|
|
});
|
2019-07-11 23:00:24 +08:00
|
|
|
|
|
|
|
await sac.connect();
|
|
|
|
|
2022-10-13 01:59:07 +08:00
|
|
|
expect(sac.exchangeForScalarToken).toBeCalledWith(tokenObject);
|
2022-05-03 23:09:07 +08:00
|
|
|
expect(sac.hasCredentials).toBeTruthy();
|
|
|
|
// @ts-ignore private property
|
2019-07-11 23:00:24 +08:00
|
|
|
expect(sac.scalarToken).toEqual('wokentoken');
|
|
|
|
});
|
2022-10-13 01:59:07 +08:00
|
|
|
|
|
|
|
describe("exchangeForScalarToken", () => {
|
|
|
|
it("should return `scalar_token` from API /register", async () => {
|
|
|
|
const sac = new ScalarAuthClient(apiUrl + 1, uiUrl);
|
|
|
|
|
|
|
|
fetchMock.postOnce("https://test.com/api1/register?v=1.1", {
|
|
|
|
body: { scalar_token: "stoken" },
|
|
|
|
});
|
|
|
|
|
|
|
|
await expect(sac.exchangeForScalarToken(tokenObject)).resolves.toBe("stoken");
|
|
|
|
});
|
|
|
|
|
|
|
|
it("should throw upon non-20x code", async () => {
|
|
|
|
const sac = new ScalarAuthClient(apiUrl + 2, uiUrl);
|
|
|
|
|
|
|
|
fetchMock.postOnce("https://test.com/api2/register?v=1.1", {
|
|
|
|
status: 500,
|
|
|
|
});
|
|
|
|
|
|
|
|
await expect(sac.exchangeForScalarToken(tokenObject)).rejects.toThrow("Scalar request failed: 500");
|
|
|
|
});
|
|
|
|
|
|
|
|
it("should throw if scalar_token is missing in response", async () => {
|
|
|
|
const sac = new ScalarAuthClient(apiUrl + 3, uiUrl);
|
|
|
|
|
|
|
|
fetchMock.postOnce("https://test.com/api3/register?v=1.1", {
|
|
|
|
body: {},
|
|
|
|
});
|
|
|
|
|
|
|
|
await expect(sac.exchangeForScalarToken(tokenObject)).rejects.toThrow("Missing scalar_token in response");
|
|
|
|
});
|
|
|
|
});
|
|
|
|
|
|
|
|
describe("registerForToken", () => {
|
|
|
|
it("should call `termsInteractionCallback` upon M_TERMS_NOT_SIGNED error", async () => {
|
|
|
|
const sac = new ScalarAuthClient(apiUrl + 4, uiUrl);
|
|
|
|
const termsInteractionCallback = jest.fn();
|
|
|
|
sac.setTermsInteractionCallback(termsInteractionCallback);
|
|
|
|
fetchMock.get("https://test.com/api4/account?scalar_token=testtoken1&v=1.1", {
|
|
|
|
body: { errcode: "M_TERMS_NOT_SIGNED" },
|
|
|
|
});
|
|
|
|
sac.exchangeForScalarToken = jest.fn(() => Promise.resolve("testtoken1"));
|
|
|
|
mocked(client.getTerms).mockResolvedValue({ policies: [] });
|
|
|
|
|
|
|
|
await expect(sac.registerForToken()).resolves.toBe("testtoken1");
|
|
|
|
});
|
|
|
|
|
|
|
|
it("should throw upon non-20x code", async () => {
|
|
|
|
const sac = new ScalarAuthClient(apiUrl + 5, uiUrl);
|
|
|
|
fetchMock.get("https://test.com/api5/account?scalar_token=testtoken2&v=1.1", {
|
|
|
|
body: { errcode: "SERVER_IS_SAD" },
|
|
|
|
status: 500,
|
|
|
|
});
|
|
|
|
sac.exchangeForScalarToken = jest.fn(() => Promise.resolve("testtoken2"));
|
|
|
|
|
|
|
|
await expect(sac.registerForToken()).rejects.toBeTruthy();
|
|
|
|
});
|
|
|
|
|
|
|
|
it("should throw if user_id is missing from response", async () => {
|
|
|
|
const sac = new ScalarAuthClient(apiUrl + 6, uiUrl);
|
|
|
|
fetchMock.get("https://test.com/api6/account?scalar_token=testtoken3&v=1.1", {
|
|
|
|
body: {},
|
|
|
|
});
|
|
|
|
sac.exchangeForScalarToken = jest.fn(() => Promise.resolve("testtoken3"));
|
|
|
|
|
|
|
|
await expect(sac.registerForToken()).rejects.toThrow("Missing user_id in response");
|
|
|
|
});
|
|
|
|
});
|
|
|
|
|
|
|
|
describe("getScalarPageTitle", () => {
|
|
|
|
let sac: ScalarAuthClient;
|
|
|
|
|
|
|
|
beforeEach(async () => {
|
|
|
|
SdkConfig.put({
|
|
|
|
integrations_rest_url: apiUrl + 7,
|
|
|
|
integrations_ui_url: uiUrl,
|
|
|
|
});
|
|
|
|
|
|
|
|
window.localStorage.setItem("mx_scalar_token_at_https://test.com/api7", "wokentoken1");
|
|
|
|
fetchMock.get("https://test.com/api7/account?scalar_token=wokentoken1&v=1.1", {
|
|
|
|
body: { user_id: client.getUserId() },
|
|
|
|
});
|
|
|
|
|
|
|
|
sac = new ScalarAuthClient(apiUrl + 7, uiUrl);
|
|
|
|
await sac.connect();
|
|
|
|
});
|
|
|
|
|
|
|
|
it("should return `cached_title` from API /widgets/title_lookup", async () => {
|
|
|
|
const url = "google.com";
|
|
|
|
fetchMock.get("https://test.com/api7/widgets/title_lookup?scalar_token=wokentoken1&curl=" + url, {
|
|
|
|
body: {
|
|
|
|
page_title_cache_item: {
|
|
|
|
cached_title: "Google",
|
|
|
|
},
|
|
|
|
},
|
|
|
|
});
|
|
|
|
|
|
|
|
await expect(sac.getScalarPageTitle(url)).resolves.toBe("Google");
|
|
|
|
});
|
|
|
|
|
|
|
|
it("should throw upon non-20x code", async () => {
|
|
|
|
const url = "yahoo.com";
|
|
|
|
fetchMock.get("https://test.com/api7/widgets/title_lookup?scalar_token=wokentoken1&curl=" + url, {
|
|
|
|
status: 500,
|
|
|
|
});
|
|
|
|
|
|
|
|
await expect(sac.getScalarPageTitle(url)).rejects.toThrow("Scalar request failed: 500");
|
|
|
|
});
|
|
|
|
});
|
|
|
|
|
|
|
|
describe("disableWidgetAssets", () => {
|
|
|
|
let sac: ScalarAuthClient;
|
|
|
|
|
|
|
|
beforeEach(async () => {
|
|
|
|
SdkConfig.put({
|
|
|
|
integrations_rest_url: apiUrl + 8,
|
|
|
|
integrations_ui_url: uiUrl,
|
|
|
|
});
|
|
|
|
|
|
|
|
window.localStorage.setItem("mx_scalar_token_at_https://test.com/api8", "wokentoken1");
|
|
|
|
fetchMock.get("https://test.com/api8/account?scalar_token=wokentoken1&v=1.1", {
|
|
|
|
body: { user_id: client.getUserId() },
|
|
|
|
});
|
|
|
|
|
|
|
|
sac = new ScalarAuthClient(apiUrl + 8, uiUrl);
|
|
|
|
await sac.connect();
|
|
|
|
});
|
|
|
|
|
|
|
|
it("should send state=disable to API /widgets/set_assets_state", async () => {
|
|
|
|
fetchMock.get("https://test.com/api8/widgets/set_assets_state?scalar_token=wokentoken1" +
|
|
|
|
"&widget_type=m.custom&widget_id=id1&state=disable", {
|
|
|
|
body: "OK",
|
|
|
|
});
|
|
|
|
|
|
|
|
await expect(sac.disableWidgetAssets(WidgetType.CUSTOM, "id1")).resolves.toBeUndefined();
|
|
|
|
});
|
|
|
|
|
|
|
|
it("should throw upon non-20x code", async () => {
|
|
|
|
fetchMock.get("https://test.com/api8/widgets/set_assets_state?scalar_token=wokentoken1" +
|
|
|
|
"&widget_type=m.custom&widget_id=id2&state=disable", {
|
|
|
|
status: 500,
|
|
|
|
});
|
|
|
|
|
|
|
|
await expect(sac.disableWidgetAssets(WidgetType.CUSTOM, "id2"))
|
|
|
|
.rejects.toThrow("Scalar request failed: 500");
|
|
|
|
});
|
|
|
|
});
|
2019-07-11 23:00:24 +08:00
|
|
|
});
|