mirror of
https://github.com/bitwarden/directory-connector
synced 2026-02-26 17:23:15 +00:00
Compare commits
1 Commits
dev-clarit
...
jslib-remo
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
a74973ccfa |
46
.github/workflows/lint.yml
vendored
46
.github/workflows/lint.yml
vendored
@@ -1,46 +0,0 @@
|
||||
name: Lint
|
||||
|
||||
on:
|
||||
workflow_dispatch:
|
||||
push:
|
||||
branches:
|
||||
- "main"
|
||||
- "rc"
|
||||
- "hotfix-rc"
|
||||
pull_request:
|
||||
|
||||
permissions:
|
||||
contents: read
|
||||
|
||||
jobs:
|
||||
|
||||
lint:
|
||||
name: Run linter
|
||||
if: ${{ startsWith(github.head_ref, 'version_bump_') == false }}
|
||||
runs-on: ubuntu-24.04
|
||||
|
||||
steps:
|
||||
- name: Check out repo
|
||||
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
|
||||
with:
|
||||
persist-credentials: false
|
||||
|
||||
- name: Get Node version
|
||||
id: retrieve-node-version
|
||||
run: |
|
||||
NODE_NVMRC=$(cat .nvmrc)
|
||||
NODE_VERSION=${NODE_NVMRC/v/''}
|
||||
echo "node_version=$NODE_VERSION" >> "$GITHUB_OUTPUT"
|
||||
|
||||
- name: Set up Node
|
||||
uses: actions/setup-node@6044e13b5dc448c55e2357c09f80417699197238 # v6.2.0
|
||||
with:
|
||||
cache: 'npm'
|
||||
cache-dependency-path: '**/package-lock.json'
|
||||
node-version: ${{ steps.retrieve-node-version.outputs.node_version }}
|
||||
|
||||
- name: Install Node dependencies
|
||||
run: npm ci
|
||||
|
||||
- name: Run ESLint and Prettier
|
||||
run: npm run lint
|
||||
@@ -1,28 +0,0 @@
|
||||
import { webcrypto } from "crypto";
|
||||
import "jest-preset-angular/setup-jest";
|
||||
|
||||
Object.defineProperty(window, "CSS", { value: null });
|
||||
Object.defineProperty(window, "getComputedStyle", {
|
||||
value: () => {
|
||||
return {
|
||||
display: "none",
|
||||
appearance: ["-webkit-appearance"],
|
||||
};
|
||||
},
|
||||
});
|
||||
|
||||
Object.defineProperty(document, "doctype", {
|
||||
value: "<!DOCTYPE html>",
|
||||
});
|
||||
Object.defineProperty(document.body.style, "transform", {
|
||||
value: () => {
|
||||
return {
|
||||
enumerable: true,
|
||||
configurable: true,
|
||||
};
|
||||
},
|
||||
});
|
||||
|
||||
Object.defineProperty(window, "crypto", {
|
||||
value: webcrypto,
|
||||
});
|
||||
@@ -1,69 +0,0 @@
|
||||
import { EncryptionType } from "@/jslib/common/src/enums/encryptionType";
|
||||
import { SymmetricCryptoKey } from "@/jslib/common/src/models/domain/symmetricCryptoKey";
|
||||
|
||||
import { makeStaticByteArray } from "../utils";
|
||||
|
||||
describe("SymmetricCryptoKey", () => {
|
||||
it("errors if no key", () => {
|
||||
const t = () => {
|
||||
new SymmetricCryptoKey(null);
|
||||
};
|
||||
|
||||
expect(t).toThrow("Must provide key");
|
||||
});
|
||||
|
||||
describe("guesses encKey from key length", () => {
|
||||
it("AesCbc256_B64", () => {
|
||||
const key = makeStaticByteArray(32);
|
||||
const cryptoKey = new SymmetricCryptoKey(key);
|
||||
|
||||
expect(cryptoKey).toEqual({
|
||||
encKey: key,
|
||||
encKeyB64: "AAECAwQFBgcICQoLDA0ODxAREhMUFRYXGBkaGxwdHh8=",
|
||||
encType: 0,
|
||||
key: key,
|
||||
keyB64: "AAECAwQFBgcICQoLDA0ODxAREhMUFRYXGBkaGxwdHh8=",
|
||||
macKey: null,
|
||||
});
|
||||
});
|
||||
|
||||
it("AesCbc128_HmacSha256_B64", () => {
|
||||
const key = makeStaticByteArray(32);
|
||||
const cryptoKey = new SymmetricCryptoKey(key, EncryptionType.AesCbc128_HmacSha256_B64);
|
||||
|
||||
expect(cryptoKey).toEqual({
|
||||
encKey: key.slice(0, 16),
|
||||
encKeyB64: "AAECAwQFBgcICQoLDA0ODw==",
|
||||
encType: 1,
|
||||
key: key,
|
||||
keyB64: "AAECAwQFBgcICQoLDA0ODxAREhMUFRYXGBkaGxwdHh8=",
|
||||
macKey: key.slice(16, 32),
|
||||
macKeyB64: "EBESExQVFhcYGRobHB0eHw==",
|
||||
});
|
||||
});
|
||||
|
||||
it("AesCbc256_HmacSha256_B64", () => {
|
||||
const key = makeStaticByteArray(64);
|
||||
const cryptoKey = new SymmetricCryptoKey(key);
|
||||
|
||||
expect(cryptoKey).toEqual({
|
||||
encKey: key.slice(0, 32),
|
||||
encKeyB64: "AAECAwQFBgcICQoLDA0ODxAREhMUFRYXGBkaGxwdHh8=",
|
||||
encType: 2,
|
||||
key: key,
|
||||
keyB64:
|
||||
"AAECAwQFBgcICQoLDA0ODxAREhMUFRYXGBkaGxwdHh8gISIjJCUmJygpKissLS4vMDEyMzQ1Njc4OTo7PD0+Pw==",
|
||||
macKey: key.slice(32, 64),
|
||||
macKeyB64: "ICEiIyQlJicoKSorLC0uLzAxMjM0NTY3ODk6Ozw9Pj8=",
|
||||
});
|
||||
});
|
||||
|
||||
it("unknown length", () => {
|
||||
const t = () => {
|
||||
new SymmetricCryptoKey(makeStaticByteArray(30));
|
||||
};
|
||||
|
||||
expect(t).toThrow("Unable to determine encType.");
|
||||
});
|
||||
});
|
||||
});
|
||||
@@ -1,127 +0,0 @@
|
||||
import { sequentialize } from "@/jslib/common/src/misc/sequentialize";
|
||||
|
||||
describe("sequentialize decorator", () => {
|
||||
it("should call the function once", async () => {
|
||||
const foo = new Foo();
|
||||
const promises = [];
|
||||
for (let i = 0; i < 10; i++) {
|
||||
promises.push(foo.bar(1));
|
||||
}
|
||||
await Promise.all(promises);
|
||||
|
||||
expect(foo.calls).toBe(1);
|
||||
});
|
||||
|
||||
it("should call the function once for each instance of the object", async () => {
|
||||
const foo = new Foo();
|
||||
const foo2 = new Foo();
|
||||
const promises = [];
|
||||
for (let i = 0; i < 10; i++) {
|
||||
promises.push(foo.bar(1));
|
||||
promises.push(foo2.bar(1));
|
||||
}
|
||||
await Promise.all(promises);
|
||||
|
||||
expect(foo.calls).toBe(1);
|
||||
expect(foo2.calls).toBe(1);
|
||||
});
|
||||
|
||||
it("should call the function once with key function", async () => {
|
||||
const foo = new Foo();
|
||||
const promises = [];
|
||||
for (let i = 0; i < 10; i++) {
|
||||
promises.push(foo.baz(1));
|
||||
}
|
||||
await Promise.all(promises);
|
||||
|
||||
expect(foo.calls).toBe(1);
|
||||
});
|
||||
|
||||
it("should call the function again when already resolved", async () => {
|
||||
const foo = new Foo();
|
||||
await foo.bar(1);
|
||||
expect(foo.calls).toBe(1);
|
||||
await foo.bar(1);
|
||||
expect(foo.calls).toBe(2);
|
||||
});
|
||||
|
||||
it("should call the function again when already resolved with a key function", async () => {
|
||||
const foo = new Foo();
|
||||
await foo.baz(1);
|
||||
expect(foo.calls).toBe(1);
|
||||
await foo.baz(1);
|
||||
expect(foo.calls).toBe(2);
|
||||
});
|
||||
|
||||
it("should call the function for each argument", async () => {
|
||||
const foo = new Foo();
|
||||
await Promise.all([foo.bar(1), foo.bar(1), foo.bar(2), foo.bar(2), foo.bar(3), foo.bar(3)]);
|
||||
expect(foo.calls).toBe(3);
|
||||
});
|
||||
|
||||
it("should call the function for each argument with key function", async () => {
|
||||
const foo = new Foo();
|
||||
await Promise.all([foo.baz(1), foo.baz(1), foo.baz(2), foo.baz(2), foo.baz(3), foo.baz(3)]);
|
||||
expect(foo.calls).toBe(3);
|
||||
});
|
||||
|
||||
it("should return correct result for each call", async () => {
|
||||
const foo = new Foo();
|
||||
const allRes: number[] = [];
|
||||
|
||||
await Promise.all([
|
||||
foo.bar(1).then((res) => allRes.push(res)),
|
||||
foo.bar(1).then((res) => allRes.push(res)),
|
||||
foo.bar(2).then((res) => allRes.push(res)),
|
||||
foo.bar(2).then((res) => allRes.push(res)),
|
||||
foo.bar(3).then((res) => allRes.push(res)),
|
||||
foo.bar(3).then((res) => allRes.push(res)),
|
||||
]);
|
||||
expect(foo.calls).toBe(3);
|
||||
expect(allRes.length).toBe(6);
|
||||
allRes.sort();
|
||||
expect(allRes).toEqual([2, 2, 4, 4, 6, 6]);
|
||||
});
|
||||
|
||||
it("should return correct result for each call with key function", async () => {
|
||||
const foo = new Foo();
|
||||
const allRes: number[] = [];
|
||||
|
||||
await Promise.all([
|
||||
foo.baz(1).then((res) => allRes.push(res)),
|
||||
foo.baz(1).then((res) => allRes.push(res)),
|
||||
foo.baz(2).then((res) => allRes.push(res)),
|
||||
foo.baz(2).then((res) => allRes.push(res)),
|
||||
foo.baz(3).then((res) => allRes.push(res)),
|
||||
foo.baz(3).then((res) => allRes.push(res)),
|
||||
]);
|
||||
expect(foo.calls).toBe(3);
|
||||
expect(allRes.length).toBe(6);
|
||||
allRes.sort();
|
||||
expect(allRes).toEqual([3, 3, 6, 6, 9, 9]);
|
||||
});
|
||||
});
|
||||
|
||||
class Foo {
|
||||
calls = 0;
|
||||
|
||||
@sequentialize((args) => "bar" + args[0])
|
||||
bar(a: number): Promise<number> {
|
||||
this.calls++;
|
||||
return new Promise((res) => {
|
||||
setTimeout(() => {
|
||||
res(a * 2);
|
||||
}, Math.random() * 100);
|
||||
});
|
||||
}
|
||||
|
||||
@sequentialize((args) => "baz" + args[0])
|
||||
baz(a: number): Promise<number> {
|
||||
this.calls++;
|
||||
return new Promise((res) => {
|
||||
setTimeout(() => {
|
||||
res(a * 3);
|
||||
}, Math.random() * 100);
|
||||
});
|
||||
}
|
||||
}
|
||||
@@ -1,110 +0,0 @@
|
||||
import { sequentialize } from "@/jslib/common/src/misc/sequentialize";
|
||||
import { throttle } from "@/jslib/common/src/misc/throttle";
|
||||
|
||||
describe("throttle decorator", () => {
|
||||
it("should call the function once at a time", async () => {
|
||||
const foo = new Foo();
|
||||
const promises = [];
|
||||
for (let i = 0; i < 10; i++) {
|
||||
promises.push(foo.bar(1));
|
||||
}
|
||||
await Promise.all(promises);
|
||||
|
||||
expect(foo.calls).toBe(10);
|
||||
});
|
||||
|
||||
it("should call the function once at a time for each object", async () => {
|
||||
const foo = new Foo();
|
||||
const foo2 = new Foo();
|
||||
const promises = [];
|
||||
for (let i = 0; i < 10; i++) {
|
||||
promises.push(foo.bar(1));
|
||||
promises.push(foo2.bar(1));
|
||||
}
|
||||
await Promise.all(promises);
|
||||
|
||||
expect(foo.calls).toBe(10);
|
||||
expect(foo2.calls).toBe(10);
|
||||
});
|
||||
|
||||
it("should call the function limit at a time", async () => {
|
||||
const foo = new Foo();
|
||||
const promises = [];
|
||||
for (let i = 0; i < 10; i++) {
|
||||
promises.push(foo.baz(1));
|
||||
}
|
||||
await Promise.all(promises);
|
||||
|
||||
expect(foo.calls).toBe(10);
|
||||
});
|
||||
|
||||
it("should call the function limit at a time for each object", async () => {
|
||||
const foo = new Foo();
|
||||
const foo2 = new Foo();
|
||||
const promises = [];
|
||||
for (let i = 0; i < 10; i++) {
|
||||
promises.push(foo.baz(1));
|
||||
promises.push(foo2.baz(1));
|
||||
}
|
||||
await Promise.all(promises);
|
||||
|
||||
expect(foo.calls).toBe(10);
|
||||
expect(foo2.calls).toBe(10);
|
||||
});
|
||||
|
||||
it("should work together with sequentialize", async () => {
|
||||
const foo = new Foo();
|
||||
const promises = [];
|
||||
for (let i = 0; i < 10; i++) {
|
||||
promises.push(foo.qux(Math.floor(i / 2) * 2));
|
||||
}
|
||||
await Promise.all(promises);
|
||||
|
||||
expect(foo.calls).toBe(5);
|
||||
});
|
||||
});
|
||||
|
||||
class Foo {
|
||||
calls = 0;
|
||||
inflight = 0;
|
||||
|
||||
@throttle(1, () => "bar")
|
||||
bar(a: number) {
|
||||
this.calls++;
|
||||
this.inflight++;
|
||||
return new Promise((res) => {
|
||||
setTimeout(() => {
|
||||
expect(this.inflight).toBe(1);
|
||||
this.inflight--;
|
||||
res(a * 2);
|
||||
}, Math.random() * 10);
|
||||
});
|
||||
}
|
||||
|
||||
@throttle(5, () => "baz")
|
||||
baz(a: number) {
|
||||
this.calls++;
|
||||
this.inflight++;
|
||||
return new Promise((res) => {
|
||||
setTimeout(() => {
|
||||
expect(this.inflight).toBeLessThanOrEqual(5);
|
||||
this.inflight--;
|
||||
res(a * 3);
|
||||
}, Math.random() * 10);
|
||||
});
|
||||
}
|
||||
|
||||
@sequentialize((args) => "qux" + args[0])
|
||||
@throttle(1, () => "qux")
|
||||
qux(a: number) {
|
||||
this.calls++;
|
||||
this.inflight++;
|
||||
return new Promise((res) => {
|
||||
setTimeout(() => {
|
||||
expect(this.inflight).toBe(1);
|
||||
this.inflight--;
|
||||
res(a * 3);
|
||||
}, Math.random() * 10);
|
||||
});
|
||||
}
|
||||
}
|
||||
@@ -1,99 +0,0 @@
|
||||
import { ConsoleLogService } from "@/jslib/common/src/services/consoleLog.service";
|
||||
|
||||
const originalConsole = console;
|
||||
let caughtMessage: any;
|
||||
|
||||
declare let console: any;
|
||||
|
||||
export function interceptConsole(interceptions: any): object {
|
||||
console = {
|
||||
log: function () {
|
||||
interceptions.log = arguments;
|
||||
},
|
||||
warn: function () {
|
||||
interceptions.warn = arguments;
|
||||
},
|
||||
error: function () {
|
||||
interceptions.error = arguments;
|
||||
},
|
||||
};
|
||||
return interceptions;
|
||||
}
|
||||
|
||||
export function restoreConsole() {
|
||||
console = originalConsole;
|
||||
}
|
||||
|
||||
describe("ConsoleLogService", () => {
|
||||
let logService: ConsoleLogService;
|
||||
beforeEach(() => {
|
||||
caughtMessage = {};
|
||||
interceptConsole(caughtMessage);
|
||||
logService = new ConsoleLogService(true);
|
||||
});
|
||||
|
||||
afterAll(() => {
|
||||
restoreConsole();
|
||||
});
|
||||
|
||||
it("filters messages below the set threshold", () => {
|
||||
logService = new ConsoleLogService(true, () => true);
|
||||
logService.debug("debug");
|
||||
logService.info("info");
|
||||
logService.warning("warning");
|
||||
logService.error("error");
|
||||
|
||||
expect(caughtMessage).toEqual({});
|
||||
});
|
||||
it("only writes debug messages in dev mode", () => {
|
||||
logService = new ConsoleLogService(false);
|
||||
|
||||
logService.debug("debug message");
|
||||
expect(caughtMessage.log).toBeUndefined();
|
||||
});
|
||||
|
||||
it("writes debug/info messages to console.log", () => {
|
||||
logService.debug("this is a debug message");
|
||||
expect(caughtMessage).toMatchObject({
|
||||
log: { "0": "this is a debug message" },
|
||||
});
|
||||
|
||||
logService.info("this is an info message");
|
||||
expect(caughtMessage).toMatchObject({
|
||||
log: { "0": "this is an info message" },
|
||||
});
|
||||
});
|
||||
it("writes warning messages to console.warn", () => {
|
||||
logService.warning("this is a warning message");
|
||||
expect(caughtMessage).toMatchObject({
|
||||
warn: { 0: "this is a warning message" },
|
||||
});
|
||||
});
|
||||
it("writes error messages to console.error", () => {
|
||||
logService.error("this is an error message");
|
||||
expect(caughtMessage).toMatchObject({
|
||||
error: { 0: "this is an error message" },
|
||||
});
|
||||
});
|
||||
|
||||
it("times with output to info", async () => {
|
||||
logService.time();
|
||||
await new Promise((r) => setTimeout(r, 250));
|
||||
const duration = logService.timeEnd();
|
||||
expect(duration[0]).toBe(0);
|
||||
expect(duration[1]).toBeGreaterThan(0);
|
||||
expect(duration[1]).toBeLessThan(500 * 10e6);
|
||||
|
||||
expect(caughtMessage).toEqual(expect.arrayContaining([]));
|
||||
expect(caughtMessage.log.length).toBe(1);
|
||||
expect(caughtMessage.log[0]).toEqual(expect.stringMatching(/^default: \d+\.?\d*ms$/));
|
||||
});
|
||||
|
||||
it("filters time output", async () => {
|
||||
logService = new ConsoleLogService(true, () => true);
|
||||
logService.time();
|
||||
logService.timeEnd();
|
||||
|
||||
expect(caughtMessage).toEqual({});
|
||||
});
|
||||
});
|
||||
@@ -1,5 +0,0 @@
|
||||
import { webcrypto } from "crypto";
|
||||
|
||||
Object.defineProperty(window, "crypto", {
|
||||
value: webcrypto,
|
||||
});
|
||||
@@ -1,6 +0,0 @@
|
||||
export enum AuthenticationStatus {
|
||||
Locked = "locked",
|
||||
Unlocked = "unlocked",
|
||||
LoggedOut = "loggedOut",
|
||||
Active = "active",
|
||||
}
|
||||
@@ -1,4 +0,0 @@
|
||||
export enum CipherRepromptType {
|
||||
None = 0,
|
||||
Password = 1,
|
||||
}
|
||||
@@ -1,6 +0,0 @@
|
||||
export enum CipherType {
|
||||
Login = 1,
|
||||
SecureNote = 2,
|
||||
Card = 3,
|
||||
Identity = 4,
|
||||
}
|
||||
@@ -1,7 +0,0 @@
|
||||
export enum EmergencyAccessStatusType {
|
||||
Invited = 0,
|
||||
Accepted = 1,
|
||||
Confirmed = 2,
|
||||
RecoveryInitiated = 3,
|
||||
RecoveryApproved = 4,
|
||||
}
|
||||
@@ -1,4 +0,0 @@
|
||||
export enum EmergencyAccessType {
|
||||
View = 0,
|
||||
Takeover = 1,
|
||||
}
|
||||
@@ -1,6 +0,0 @@
|
||||
export enum FieldType {
|
||||
Text = 0,
|
||||
Hidden = 1,
|
||||
Boolean = 2,
|
||||
Linked = 3,
|
||||
}
|
||||
@@ -1,4 +0,0 @@
|
||||
export enum FileUploadType {
|
||||
Direct = 0,
|
||||
Azure = 1,
|
||||
}
|
||||
@@ -1,4 +0,0 @@
|
||||
export enum HashPurpose {
|
||||
ServerAuthorization = 1,
|
||||
LocalAuthorization = 2,
|
||||
}
|
||||
@@ -1,4 +0,0 @@
|
||||
export enum KeySuffixOptions {
|
||||
Auto = "auto",
|
||||
Biometric = "biometric",
|
||||
}
|
||||
@@ -1,20 +0,0 @@
|
||||
export enum NotificationType {
|
||||
SyncCipherUpdate = 0,
|
||||
SyncCipherCreate = 1,
|
||||
SyncLoginDelete = 2,
|
||||
SyncFolderDelete = 3,
|
||||
SyncCiphers = 4,
|
||||
|
||||
SyncVault = 5,
|
||||
SyncOrgKeys = 6,
|
||||
SyncFolderCreate = 7,
|
||||
SyncFolderUpdate = 8,
|
||||
SyncCipherDelete = 9,
|
||||
SyncSettings = 10,
|
||||
|
||||
LogOut = 11,
|
||||
|
||||
SyncSendCreate = 12,
|
||||
SyncSendUpdate = 13,
|
||||
SyncSendDelete = 14,
|
||||
}
|
||||
@@ -1,5 +0,0 @@
|
||||
export enum OrganizationUserStatusType {
|
||||
Invited = 0,
|
||||
Accepted = 1,
|
||||
Confirmed = 2,
|
||||
}
|
||||
@@ -1,7 +0,0 @@
|
||||
export enum OrganizationUserType {
|
||||
Owner = 0,
|
||||
Admin = 1,
|
||||
User = 2,
|
||||
Manager = 3,
|
||||
Custom = 4,
|
||||
}
|
||||
@@ -1,11 +0,0 @@
|
||||
export enum PaymentMethodType {
|
||||
Card = 0,
|
||||
BankAccount = 1,
|
||||
PayPal = 2,
|
||||
BitPay = 3,
|
||||
Credit = 4,
|
||||
WireTransfer = 5,
|
||||
AppleInApp = 6,
|
||||
GoogleInApp = 7,
|
||||
Check = 8,
|
||||
}
|
||||
@@ -1,27 +0,0 @@
|
||||
export enum Permissions {
|
||||
AccessEventLogs,
|
||||
AccessImportExport,
|
||||
AccessReports,
|
||||
/**
|
||||
* @deprecated Sep 29 2021: This permission has been split out to `createNewCollections`, `editAnyCollection`, and
|
||||
* `deleteAnyCollection`. It exists here for backwards compatibility with Server versions <= 1.43.0
|
||||
*/
|
||||
ManageAllCollections,
|
||||
/**
|
||||
* @deprecated Sep 29 2021: This permission has been split out to `editAssignedCollections` and
|
||||
* `deleteAssignedCollections`. It exists here for backwards compatibility with Server versions <= 1.43.0
|
||||
*/
|
||||
ManageAssignedCollections,
|
||||
ManageGroups,
|
||||
ManageOrganization,
|
||||
ManagePolicies,
|
||||
ManageProvider,
|
||||
ManageUsers,
|
||||
ManageUsersPassword,
|
||||
CreateNewCollections,
|
||||
EditAnyCollection,
|
||||
DeleteAnyCollection,
|
||||
EditAssignedCollections,
|
||||
DeleteAssignedCollections,
|
||||
ManageSso,
|
||||
}
|
||||
@@ -1,3 +0,0 @@
|
||||
export enum PlanSponsorshipType {
|
||||
FamiliesForEnterprise = 0,
|
||||
}
|
||||
@@ -1,14 +0,0 @@
|
||||
export enum PlanType {
|
||||
Free = 0,
|
||||
FamiliesAnnually2019 = 1,
|
||||
TeamsMonthly2019 = 2,
|
||||
TeamsAnnually2019 = 3,
|
||||
EnterpriseMonthly2019 = 4,
|
||||
EnterpriseAnnually2019 = 5,
|
||||
Custom = 6,
|
||||
FamiliesAnnually = 7,
|
||||
TeamsMonthly = 8,
|
||||
TeamsAnnually = 9,
|
||||
EnterpriseMonthly = 10,
|
||||
EnterpriseAnnually = 11,
|
||||
}
|
||||
@@ -1,6 +0,0 @@
|
||||
export enum ProductType {
|
||||
Free = 0,
|
||||
Families = 1,
|
||||
Teams = 2,
|
||||
Enterprise = 3,
|
||||
}
|
||||
@@ -1,5 +0,0 @@
|
||||
export enum ProviderUserStatusType {
|
||||
Invited = 0,
|
||||
Accepted = 1,
|
||||
Confirmed = 2,
|
||||
}
|
||||
@@ -1,4 +0,0 @@
|
||||
export enum ProviderUserType {
|
||||
ProviderAdmin = 0,
|
||||
ServiceUser = 1,
|
||||
}
|
||||
@@ -1,33 +0,0 @@
|
||||
export enum SsoType {
|
||||
None = 0,
|
||||
OpenIdConnect = 1,
|
||||
Saml2 = 2,
|
||||
}
|
||||
|
||||
export enum OpenIdConnectRedirectBehavior {
|
||||
RedirectGet = 0,
|
||||
FormPost = 1,
|
||||
}
|
||||
|
||||
export enum Saml2BindingType {
|
||||
HttpRedirect = 1,
|
||||
HttpPost = 2,
|
||||
}
|
||||
|
||||
export enum Saml2NameIdFormat {
|
||||
NotConfigured = 0,
|
||||
Unspecified = 1,
|
||||
EmailAddress = 2,
|
||||
X509SubjectName = 3,
|
||||
WindowsDomainQualifiedName = 4,
|
||||
KerberosPrincipalName = 5,
|
||||
EntityIdentifier = 6,
|
||||
Persistent = 7,
|
||||
Transient = 8,
|
||||
}
|
||||
|
||||
export enum Saml2SigningBehavior {
|
||||
IfIdpWantAuthnRequestsSigned = 0,
|
||||
Always = 1,
|
||||
Never = 3,
|
||||
}
|
||||
@@ -1,7 +0,0 @@
|
||||
export enum TransactionType {
|
||||
Charge = 0,
|
||||
Credit = 1,
|
||||
PromotionalCredit = 2,
|
||||
ReferralCredit = 3,
|
||||
Refund = 4,
|
||||
}
|
||||
@@ -1,8 +0,0 @@
|
||||
export enum UriMatchType {
|
||||
Domain = 0,
|
||||
Host = 1,
|
||||
StartsWith = 2,
|
||||
Exact = 3,
|
||||
RegularExpression = 4,
|
||||
Never = 5,
|
||||
}
|
||||
@@ -1,13 +0,0 @@
|
||||
import { GlobalState } from "../models/domain/globalState";
|
||||
|
||||
export class GlobalStateFactory<T extends GlobalState = GlobalState> {
|
||||
private globalStateConstructor: new (init: Partial<T>) => T;
|
||||
|
||||
constructor(globalStateConstructor: new (init: Partial<T>) => T) {
|
||||
this.globalStateConstructor = globalStateConstructor;
|
||||
}
|
||||
|
||||
create(args?: Partial<T>) {
|
||||
return new this.globalStateConstructor(args);
|
||||
}
|
||||
}
|
||||
@@ -1,72 +0,0 @@
|
||||
import { ITreeNodeObject, TreeNode } from "../models/domain/treeNode";
|
||||
|
||||
export class ServiceUtils {
|
||||
static nestedTraverse(
|
||||
nodeTree: TreeNode<ITreeNodeObject>[],
|
||||
partIndex: number,
|
||||
parts: string[],
|
||||
obj: ITreeNodeObject,
|
||||
parent: ITreeNodeObject,
|
||||
delimiter: string,
|
||||
) {
|
||||
if (parts.length <= partIndex) {
|
||||
return;
|
||||
}
|
||||
|
||||
const end = partIndex === parts.length - 1;
|
||||
const partName = parts[partIndex];
|
||||
|
||||
for (let i = 0; i < nodeTree.length; i++) {
|
||||
if (nodeTree[i].node.name !== parts[partIndex]) {
|
||||
continue;
|
||||
}
|
||||
if (end && nodeTree[i].node.id !== obj.id) {
|
||||
// Another node with the same name.
|
||||
nodeTree.push(new TreeNode(obj, partName, parent));
|
||||
return;
|
||||
}
|
||||
ServiceUtils.nestedTraverse(
|
||||
nodeTree[i].children,
|
||||
partIndex + 1,
|
||||
parts,
|
||||
obj,
|
||||
nodeTree[i].node,
|
||||
delimiter,
|
||||
);
|
||||
return;
|
||||
}
|
||||
|
||||
if (nodeTree.filter((n) => n.node.name === partName).length === 0) {
|
||||
if (end) {
|
||||
nodeTree.push(new TreeNode(obj, partName, parent));
|
||||
return;
|
||||
}
|
||||
const newPartName = parts[partIndex] + delimiter + parts[partIndex + 1];
|
||||
ServiceUtils.nestedTraverse(
|
||||
nodeTree,
|
||||
0,
|
||||
[newPartName, ...parts.slice(partIndex + 2)],
|
||||
obj,
|
||||
parent,
|
||||
delimiter,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
static getTreeNodeObject(
|
||||
nodeTree: TreeNode<ITreeNodeObject>[],
|
||||
id: string,
|
||||
): TreeNode<ITreeNodeObject> {
|
||||
for (let i = 0; i < nodeTree.length; i++) {
|
||||
if (nodeTree[i].node.id === id) {
|
||||
return nodeTree[i];
|
||||
} else if (nodeTree[i].children != null) {
|
||||
const node = ServiceUtils.getTreeNodeObject(nodeTree[i].children, id);
|
||||
if (node !== null) {
|
||||
return node;
|
||||
}
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
||||
@@ -1,69 +0,0 @@
|
||||
/**
|
||||
* Use as a Decorator on async functions, it will limit how many times the function can be
|
||||
* in-flight at a time.
|
||||
*
|
||||
* Calls beyond the limit will be queued, and run when one of the active calls finishes
|
||||
*/
|
||||
export function throttle(limit: number, throttleKey: (args: any[]) => string) {
|
||||
return <T>(
|
||||
target: any,
|
||||
propertyKey: string | symbol,
|
||||
descriptor: TypedPropertyDescriptor<(...args: any[]) => Promise<T>>,
|
||||
) => {
|
||||
const originalMethod: () => Promise<T> = descriptor.value;
|
||||
const allThrottles = new Map<any, Map<string, (() => void)[]>>();
|
||||
|
||||
const getThrottles = (obj: any) => {
|
||||
let throttles = allThrottles.get(obj);
|
||||
if (throttles != null) {
|
||||
return throttles;
|
||||
}
|
||||
throttles = new Map<string, (() => void)[]>();
|
||||
allThrottles.set(obj, throttles);
|
||||
return throttles;
|
||||
};
|
||||
|
||||
return {
|
||||
value: function (...args: any[]) {
|
||||
const throttles = getThrottles(this);
|
||||
const argsThrottleKey = throttleKey(args);
|
||||
let queue = throttles.get(argsThrottleKey);
|
||||
if (queue == null) {
|
||||
queue = [];
|
||||
throttles.set(argsThrottleKey, queue);
|
||||
}
|
||||
|
||||
return new Promise<T>((resolve, reject) => {
|
||||
const exec = () => {
|
||||
const onFinally = () => {
|
||||
queue.splice(queue.indexOf(exec), 1);
|
||||
if (queue.length >= limit) {
|
||||
queue[limit - 1]();
|
||||
} else if (queue.length === 0) {
|
||||
throttles.delete(argsThrottleKey);
|
||||
if (throttles.size === 0) {
|
||||
allThrottles.delete(this);
|
||||
}
|
||||
}
|
||||
};
|
||||
originalMethod
|
||||
.apply(this, args)
|
||||
.then((val: any) => {
|
||||
onFinally();
|
||||
return val;
|
||||
})
|
||||
.catch((err: any) => {
|
||||
onFinally();
|
||||
throw err;
|
||||
})
|
||||
.then(resolve, reject);
|
||||
};
|
||||
queue.push(exec);
|
||||
if (queue.length <= limit) {
|
||||
exec();
|
||||
}
|
||||
});
|
||||
},
|
||||
};
|
||||
};
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,55 +0,0 @@
|
||||
import { BaseResponse } from "../response/baseResponse";
|
||||
|
||||
export class PermissionsApi extends BaseResponse {
|
||||
accessEventLogs: boolean;
|
||||
accessImportExport: boolean;
|
||||
accessReports: boolean;
|
||||
/**
|
||||
* @deprecated Sep 29 2021: This permission has been split out to `createNewCollections`, `editAnyCollection`, and
|
||||
* `deleteAnyCollection`. It exists here for backwards compatibility with Server versions <= 1.43.0
|
||||
*/
|
||||
manageAllCollections: boolean;
|
||||
createNewCollections: boolean;
|
||||
editAnyCollection: boolean;
|
||||
deleteAnyCollection: boolean;
|
||||
/**
|
||||
* @deprecated Sep 29 2021: This permission has been split out to `editAssignedCollections` and
|
||||
* `deleteAssignedCollections`. It exists here for backwards compatibility with Server versions <= 1.43.0
|
||||
*/
|
||||
manageAssignedCollections: boolean;
|
||||
editAssignedCollections: boolean;
|
||||
deleteAssignedCollections: boolean;
|
||||
manageCiphers: boolean;
|
||||
manageGroups: boolean;
|
||||
manageSso: boolean;
|
||||
managePolicies: boolean;
|
||||
manageUsers: boolean;
|
||||
manageResetPassword: boolean;
|
||||
|
||||
constructor(data: any = null) {
|
||||
super(data);
|
||||
if (data == null) {
|
||||
return this;
|
||||
}
|
||||
this.accessEventLogs = this.getResponseProperty("AccessEventLogs");
|
||||
this.accessImportExport = this.getResponseProperty("AccessImportExport");
|
||||
this.accessReports = this.getResponseProperty("AccessReports");
|
||||
|
||||
// For backwards compatibility with Server <= 1.43.0
|
||||
this.manageAllCollections = this.getResponseProperty("ManageAllCollections");
|
||||
this.manageAssignedCollections = this.getResponseProperty("ManageAssignedCollections");
|
||||
|
||||
this.createNewCollections = this.getResponseProperty("CreateNewCollections");
|
||||
this.editAnyCollection = this.getResponseProperty("EditAnyCollection");
|
||||
this.deleteAnyCollection = this.getResponseProperty("DeleteAnyCollection");
|
||||
this.editAssignedCollections = this.getResponseProperty("EditAssignedCollections");
|
||||
this.deleteAssignedCollections = this.getResponseProperty("DeleteAssignedCollections");
|
||||
|
||||
this.manageCiphers = this.getResponseProperty("ManageCiphers");
|
||||
this.manageGroups = this.getResponseProperty("ManageGroups");
|
||||
this.manageSso = this.getResponseProperty("ManageSso");
|
||||
this.managePolicies = this.getResponseProperty("ManagePolicies");
|
||||
this.manageUsers = this.getResponseProperty("ManageUsers");
|
||||
this.manageResetPassword = this.getResponseProperty("ManageResetPassword");
|
||||
}
|
||||
}
|
||||
@@ -1,136 +0,0 @@
|
||||
import {
|
||||
OpenIdConnectRedirectBehavior,
|
||||
Saml2BindingType,
|
||||
Saml2NameIdFormat,
|
||||
Saml2SigningBehavior,
|
||||
SsoType,
|
||||
} from "../../enums/ssoEnums";
|
||||
import { BaseResponse } from "../response/baseResponse";
|
||||
import { SsoConfigView } from "../view/ssoConfigView";
|
||||
|
||||
export class SsoConfigApi extends BaseResponse {
|
||||
static fromView(view: SsoConfigView, api = new SsoConfigApi()) {
|
||||
api.configType = view.configType;
|
||||
|
||||
api.keyConnectorEnabled = view.keyConnectorEnabled;
|
||||
api.keyConnectorUrl = view.keyConnectorUrl;
|
||||
|
||||
if (api.configType === SsoType.OpenIdConnect) {
|
||||
api.authority = view.openId.authority;
|
||||
api.clientId = view.openId.clientId;
|
||||
api.clientSecret = view.openId.clientSecret;
|
||||
api.metadataAddress = view.openId.metadataAddress;
|
||||
api.redirectBehavior = view.openId.redirectBehavior;
|
||||
api.getClaimsFromUserInfoEndpoint = view.openId.getClaimsFromUserInfoEndpoint;
|
||||
api.additionalScopes = view.openId.additionalScopes;
|
||||
api.additionalUserIdClaimTypes = view.openId.additionalUserIdClaimTypes;
|
||||
api.additionalEmailClaimTypes = view.openId.additionalEmailClaimTypes;
|
||||
api.additionalNameClaimTypes = view.openId.additionalNameClaimTypes;
|
||||
api.acrValues = view.openId.acrValues;
|
||||
api.expectedReturnAcrValue = view.openId.expectedReturnAcrValue;
|
||||
} else if (api.configType === SsoType.Saml2) {
|
||||
api.spNameIdFormat = view.saml.spNameIdFormat;
|
||||
api.spOutboundSigningAlgorithm = view.saml.spOutboundSigningAlgorithm;
|
||||
api.spSigningBehavior = view.saml.spSigningBehavior;
|
||||
api.spMinIncomingSigningAlgorithm = view.saml.spMinIncomingSigningAlgorithm;
|
||||
api.spWantAssertionsSigned = view.saml.spWantAssertionsSigned;
|
||||
api.spValidateCertificates = view.saml.spValidateCertificates;
|
||||
|
||||
api.idpEntityId = view.saml.idpEntityId;
|
||||
api.idpBindingType = view.saml.idpBindingType;
|
||||
api.idpSingleSignOnServiceUrl = view.saml.idpSingleSignOnServiceUrl;
|
||||
api.idpSingleLogoutServiceUrl = view.saml.idpSingleLogoutServiceUrl;
|
||||
api.idpX509PublicCert = view.saml.idpX509PublicCert;
|
||||
api.idpOutboundSigningAlgorithm = view.saml.idpOutboundSigningAlgorithm;
|
||||
api.idpAllowUnsolicitedAuthnResponse = view.saml.idpAllowUnsolicitedAuthnResponse;
|
||||
api.idpWantAuthnRequestsSigned = view.saml.idpWantAuthnRequestsSigned;
|
||||
|
||||
// Value is inverted in the api model (disable instead of allow)
|
||||
api.idpDisableOutboundLogoutRequests = !view.saml.idpAllowOutboundLogoutRequests;
|
||||
}
|
||||
|
||||
return api;
|
||||
}
|
||||
configType: SsoType;
|
||||
|
||||
keyConnectorEnabled: boolean;
|
||||
keyConnectorUrl: string;
|
||||
|
||||
// OpenId
|
||||
authority: string;
|
||||
clientId: string;
|
||||
clientSecret: string;
|
||||
metadataAddress: string;
|
||||
redirectBehavior: OpenIdConnectRedirectBehavior;
|
||||
getClaimsFromUserInfoEndpoint: boolean;
|
||||
additionalScopes: string;
|
||||
additionalUserIdClaimTypes: string;
|
||||
additionalEmailClaimTypes: string;
|
||||
additionalNameClaimTypes: string;
|
||||
acrValues: string;
|
||||
expectedReturnAcrValue: string;
|
||||
|
||||
// SAML
|
||||
spNameIdFormat: Saml2NameIdFormat;
|
||||
spOutboundSigningAlgorithm: string;
|
||||
spSigningBehavior: Saml2SigningBehavior;
|
||||
spMinIncomingSigningAlgorithm: boolean;
|
||||
spWantAssertionsSigned: boolean;
|
||||
spValidateCertificates: boolean;
|
||||
|
||||
idpEntityId: string;
|
||||
idpBindingType: Saml2BindingType;
|
||||
idpSingleSignOnServiceUrl: string;
|
||||
idpSingleLogoutServiceUrl: string;
|
||||
idpX509PublicCert: string;
|
||||
idpOutboundSigningAlgorithm: string;
|
||||
idpAllowUnsolicitedAuthnResponse: boolean;
|
||||
idpDisableOutboundLogoutRequests: boolean;
|
||||
idpWantAuthnRequestsSigned: boolean;
|
||||
|
||||
constructor(data: any = null) {
|
||||
super(data);
|
||||
if (data == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
this.configType = this.getResponseProperty("ConfigType");
|
||||
|
||||
this.keyConnectorEnabled = this.getResponseProperty("KeyConnectorEnabled");
|
||||
this.keyConnectorUrl = this.getResponseProperty("KeyConnectorUrl");
|
||||
|
||||
this.authority = this.getResponseProperty("Authority");
|
||||
this.clientId = this.getResponseProperty("ClientId");
|
||||
this.clientSecret = this.getResponseProperty("ClientSecret");
|
||||
this.metadataAddress = this.getResponseProperty("MetadataAddress");
|
||||
this.redirectBehavior = this.getResponseProperty("RedirectBehavior");
|
||||
this.getClaimsFromUserInfoEndpoint = this.getResponseProperty("GetClaimsFromUserInfoEndpoint");
|
||||
this.additionalScopes = this.getResponseProperty("AdditionalScopes");
|
||||
this.additionalUserIdClaimTypes = this.getResponseProperty("AdditionalUserIdClaimTypes");
|
||||
this.additionalEmailClaimTypes = this.getResponseProperty("AdditionalEmailClaimTypes");
|
||||
this.additionalNameClaimTypes = this.getResponseProperty("AdditionalNameClaimTypes");
|
||||
this.acrValues = this.getResponseProperty("AcrValues");
|
||||
this.expectedReturnAcrValue = this.getResponseProperty("ExpectedReturnAcrValue");
|
||||
|
||||
this.spNameIdFormat = this.getResponseProperty("SpNameIdFormat");
|
||||
this.spOutboundSigningAlgorithm = this.getResponseProperty("SpOutboundSigningAlgorithm");
|
||||
this.spSigningBehavior = this.getResponseProperty("SpSigningBehavior");
|
||||
this.spMinIncomingSigningAlgorithm = this.getResponseProperty("SpMinIncomingSigningAlgorithm");
|
||||
this.spWantAssertionsSigned = this.getResponseProperty("SpWantAssertionsSigned");
|
||||
this.spValidateCertificates = this.getResponseProperty("SpValidateCertificates");
|
||||
|
||||
this.idpEntityId = this.getResponseProperty("IdpEntityId");
|
||||
this.idpBindingType = this.getResponseProperty("IdpBindingType");
|
||||
this.idpSingleSignOnServiceUrl = this.getResponseProperty("IdpSingleSignOnServiceUrl");
|
||||
this.idpSingleLogoutServiceUrl = this.getResponseProperty("IdpSingleLogoutServiceUrl");
|
||||
this.idpX509PublicCert = this.getResponseProperty("IdpX509PublicCert");
|
||||
this.idpOutboundSigningAlgorithm = this.getResponseProperty("IdpOutboundSigningAlgorithm");
|
||||
this.idpAllowUnsolicitedAuthnResponse = this.getResponseProperty(
|
||||
"IdpAllowUnsolicitedAuthnResponse",
|
||||
);
|
||||
this.idpDisableOutboundLogoutRequests = this.getResponseProperty(
|
||||
"IdpDisableOutboundLogoutRequests",
|
||||
);
|
||||
this.idpWantAuthnRequestsSigned = this.getResponseProperty("IdpWantAuthnRequestsSigned");
|
||||
}
|
||||
}
|
||||
@@ -1,78 +0,0 @@
|
||||
import { OrganizationUserStatusType } from "../../enums/organizationUserStatusType";
|
||||
import { OrganizationUserType } from "../../enums/organizationUserType";
|
||||
import { ProductType } from "../../enums/productType";
|
||||
import { PermissionsApi } from "../api/permissionsApi";
|
||||
import { ProfileOrganizationResponse } from "../response/profileOrganizationResponse";
|
||||
|
||||
export class OrganizationData {
|
||||
id: string;
|
||||
name: string;
|
||||
status: OrganizationUserStatusType;
|
||||
type: OrganizationUserType;
|
||||
enabled: boolean;
|
||||
usePolicies: boolean;
|
||||
useGroups: boolean;
|
||||
useDirectory: boolean;
|
||||
useEvents: boolean;
|
||||
useTotp: boolean;
|
||||
use2fa: boolean;
|
||||
useApi: boolean;
|
||||
useSso: boolean;
|
||||
useKeyConnector: boolean;
|
||||
useResetPassword: boolean;
|
||||
selfHost: boolean;
|
||||
usersGetPremium: boolean;
|
||||
seats: number;
|
||||
maxCollections: number;
|
||||
maxStorageGb?: number;
|
||||
ssoBound: boolean;
|
||||
identifier: string;
|
||||
permissions: PermissionsApi;
|
||||
resetPasswordEnrolled: boolean;
|
||||
userId: string;
|
||||
hasPublicAndPrivateKeys: boolean;
|
||||
providerId: string;
|
||||
providerName: string;
|
||||
isProviderUser: boolean;
|
||||
familySponsorshipFriendlyName: string;
|
||||
familySponsorshipAvailable: boolean;
|
||||
planProductType: ProductType;
|
||||
keyConnectorEnabled: boolean;
|
||||
keyConnectorUrl: string;
|
||||
|
||||
constructor(response: ProfileOrganizationResponse) {
|
||||
this.id = response.id;
|
||||
this.name = response.name;
|
||||
this.status = response.status;
|
||||
this.type = response.type;
|
||||
this.enabled = response.enabled;
|
||||
this.usePolicies = response.usePolicies;
|
||||
this.useGroups = response.useGroups;
|
||||
this.useDirectory = response.useDirectory;
|
||||
this.useEvents = response.useEvents;
|
||||
this.useTotp = response.useTotp;
|
||||
this.use2fa = response.use2fa;
|
||||
this.useApi = response.useApi;
|
||||
this.useSso = response.useSso;
|
||||
this.useKeyConnector = response.useKeyConnector;
|
||||
this.useResetPassword = response.useResetPassword;
|
||||
this.selfHost = response.selfHost;
|
||||
this.usersGetPremium = response.usersGetPremium;
|
||||
this.seats = response.seats;
|
||||
this.maxCollections = response.maxCollections;
|
||||
this.maxStorageGb = response.maxStorageGb;
|
||||
this.ssoBound = response.ssoBound;
|
||||
this.identifier = response.identifier;
|
||||
this.permissions = response.permissions;
|
||||
this.resetPasswordEnrolled = response.resetPasswordEnrolled;
|
||||
this.userId = response.userId;
|
||||
this.hasPublicAndPrivateKeys = response.hasPublicAndPrivateKeys;
|
||||
this.providerId = response.providerId;
|
||||
this.providerName = response.providerName;
|
||||
this.familySponsorshipFriendlyName = response.familySponsorshipFriendlyName;
|
||||
this.familySponsorshipAvailable = response.familySponsorshipAvailable;
|
||||
this.planProductType = response.planProductType;
|
||||
this.keyConnectorEnabled = response.keyConnectorEnabled;
|
||||
this.keyConnectorUrl = response.keyConnectorUrl;
|
||||
}
|
||||
}
|
||||
@@ -1,23 +0,0 @@
|
||||
import { ProviderUserStatusType } from "../../enums/providerUserStatusType";
|
||||
import { ProviderUserType } from "../../enums/providerUserType";
|
||||
import { ProfileProviderResponse } from "../response/profileProviderResponse";
|
||||
|
||||
export class ProviderData {
|
||||
id: string;
|
||||
name: string;
|
||||
status: ProviderUserStatusType;
|
||||
type: ProviderUserType;
|
||||
enabled: boolean;
|
||||
userId: string;
|
||||
useEvents: boolean;
|
||||
|
||||
constructor(response: ProfileProviderResponse) {
|
||||
this.id = response.id;
|
||||
this.name = response.name;
|
||||
this.status = response.status;
|
||||
this.type = response.type;
|
||||
this.enabled = response.enabled;
|
||||
this.userId = response.userId;
|
||||
this.useEvents = response.useEvents;
|
||||
}
|
||||
}
|
||||
@@ -1,3 +0,0 @@
|
||||
export class EncArrayBuffer {
|
||||
constructor(public buffer: ArrayBuffer) {}
|
||||
}
|
||||
@@ -1,8 +0,0 @@
|
||||
import { SymmetricCryptoKey } from "./symmetricCryptoKey";
|
||||
|
||||
export class EncryptedObject {
|
||||
iv: ArrayBuffer;
|
||||
data: ArrayBuffer;
|
||||
mac: ArrayBuffer;
|
||||
key: SymmetricCryptoKey;
|
||||
}
|
||||
@@ -1,40 +0,0 @@
|
||||
import { StateVersion } from "../../enums/stateVersion";
|
||||
import { ThemeType } from "../../enums/themeType";
|
||||
|
||||
import { EnvironmentUrls } from "./environmentUrls";
|
||||
import { WindowState } from "./windowState";
|
||||
|
||||
export class GlobalState {
|
||||
enableAlwaysOnTop?: boolean;
|
||||
installedVersion?: string;
|
||||
locale?: string = "en";
|
||||
organizationInvitation?: any;
|
||||
ssoCodeVerifier?: string;
|
||||
ssoOrganizationIdentifier?: string;
|
||||
ssoState?: string;
|
||||
rememberedEmail?: string;
|
||||
theme?: ThemeType = ThemeType.System;
|
||||
window?: WindowState = new WindowState();
|
||||
twoFactorToken?: string;
|
||||
disableFavicon?: boolean;
|
||||
biometricAwaitingAcceptance?: boolean;
|
||||
biometricFingerprintValidated?: boolean;
|
||||
vaultTimeout?: number;
|
||||
vaultTimeoutAction?: string;
|
||||
loginRedirect?: any;
|
||||
mainWindowSize?: number;
|
||||
enableBiometrics?: boolean;
|
||||
biometricText?: string;
|
||||
noAutoPromptBiometrics?: boolean;
|
||||
noAutoPromptBiometricsText?: string;
|
||||
stateVersion: StateVersion = StateVersion.One;
|
||||
environmentUrls: EnvironmentUrls = new EnvironmentUrls();
|
||||
enableTray?: boolean;
|
||||
enableMinimizeToTray?: boolean;
|
||||
enableCloseToTray?: boolean;
|
||||
enableStartToTray?: boolean;
|
||||
openAtLogin?: boolean;
|
||||
alwaysShowDock?: boolean;
|
||||
enableBrowserIntegration?: boolean;
|
||||
enableBrowserIntegrationFingerprint?: boolean;
|
||||
}
|
||||
@@ -1,184 +0,0 @@
|
||||
import { OrganizationUserStatusType } from "../../enums/organizationUserStatusType";
|
||||
import { OrganizationUserType } from "../../enums/organizationUserType";
|
||||
import { ProductType } from "../../enums/productType";
|
||||
import { PermissionsApi } from "../api/permissionsApi";
|
||||
import { OrganizationData } from "../data/organizationData";
|
||||
|
||||
export class Organization {
|
||||
id: string;
|
||||
name: string;
|
||||
status: OrganizationUserStatusType;
|
||||
type: OrganizationUserType;
|
||||
enabled: boolean;
|
||||
usePolicies: boolean;
|
||||
useGroups: boolean;
|
||||
useDirectory: boolean;
|
||||
useEvents: boolean;
|
||||
useTotp: boolean;
|
||||
use2fa: boolean;
|
||||
useApi: boolean;
|
||||
useSso: boolean;
|
||||
useKeyConnector: boolean;
|
||||
useResetPassword: boolean;
|
||||
selfHost: boolean;
|
||||
usersGetPremium: boolean;
|
||||
seats: number;
|
||||
maxCollections: number;
|
||||
maxStorageGb?: number;
|
||||
ssoBound: boolean;
|
||||
identifier: string;
|
||||
permissions: PermissionsApi;
|
||||
resetPasswordEnrolled: boolean;
|
||||
userId: string;
|
||||
hasPublicAndPrivateKeys: boolean;
|
||||
providerId: string;
|
||||
providerName: string;
|
||||
isProviderUser: boolean;
|
||||
familySponsorshipFriendlyName: string;
|
||||
familySponsorshipAvailable: boolean;
|
||||
planProductType: ProductType;
|
||||
keyConnectorEnabled: boolean;
|
||||
keyConnectorUrl: string;
|
||||
|
||||
constructor(obj?: OrganizationData) {
|
||||
if (obj == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
this.id = obj.id;
|
||||
this.name = obj.name;
|
||||
this.status = obj.status;
|
||||
this.type = obj.type;
|
||||
this.enabled = obj.enabled;
|
||||
this.usePolicies = obj.usePolicies;
|
||||
this.useGroups = obj.useGroups;
|
||||
this.useDirectory = obj.useDirectory;
|
||||
this.useEvents = obj.useEvents;
|
||||
this.useTotp = obj.useTotp;
|
||||
this.use2fa = obj.use2fa;
|
||||
this.useApi = obj.useApi;
|
||||
this.useSso = obj.useSso;
|
||||
this.useKeyConnector = obj.useKeyConnector;
|
||||
this.useResetPassword = obj.useResetPassword;
|
||||
this.selfHost = obj.selfHost;
|
||||
this.usersGetPremium = obj.usersGetPremium;
|
||||
this.seats = obj.seats;
|
||||
this.maxCollections = obj.maxCollections;
|
||||
this.maxStorageGb = obj.maxStorageGb;
|
||||
this.ssoBound = obj.ssoBound;
|
||||
this.identifier = obj.identifier;
|
||||
this.permissions = obj.permissions;
|
||||
this.resetPasswordEnrolled = obj.resetPasswordEnrolled;
|
||||
this.userId = obj.userId;
|
||||
this.hasPublicAndPrivateKeys = obj.hasPublicAndPrivateKeys;
|
||||
this.providerId = obj.providerId;
|
||||
this.providerName = obj.providerName;
|
||||
this.isProviderUser = obj.isProviderUser;
|
||||
this.familySponsorshipFriendlyName = obj.familySponsorshipFriendlyName;
|
||||
this.familySponsorshipAvailable = obj.familySponsorshipAvailable;
|
||||
this.planProductType = obj.planProductType;
|
||||
this.keyConnectorEnabled = obj.keyConnectorEnabled;
|
||||
this.keyConnectorUrl = obj.keyConnectorUrl;
|
||||
}
|
||||
|
||||
get canAccess() {
|
||||
if (this.type === OrganizationUserType.Owner) {
|
||||
return true;
|
||||
}
|
||||
return this.enabled && this.status === OrganizationUserStatusType.Confirmed;
|
||||
}
|
||||
|
||||
get isManager() {
|
||||
return (
|
||||
this.type === OrganizationUserType.Manager ||
|
||||
this.type === OrganizationUserType.Owner ||
|
||||
this.type === OrganizationUserType.Admin
|
||||
);
|
||||
}
|
||||
|
||||
get isAdmin() {
|
||||
return this.type === OrganizationUserType.Owner || this.type === OrganizationUserType.Admin;
|
||||
}
|
||||
|
||||
get isOwner() {
|
||||
return this.type === OrganizationUserType.Owner || this.isProviderUser;
|
||||
}
|
||||
|
||||
get canAccessEventLogs() {
|
||||
return this.isAdmin || this.permissions.accessEventLogs;
|
||||
}
|
||||
|
||||
get canAccessImportExport() {
|
||||
return this.isAdmin || this.permissions.accessImportExport;
|
||||
}
|
||||
|
||||
get canAccessReports() {
|
||||
return this.isAdmin || this.permissions.accessReports;
|
||||
}
|
||||
|
||||
get canCreateNewCollections() {
|
||||
return (
|
||||
this.isManager ||
|
||||
(this.permissions.createNewCollections ?? this.permissions.manageAllCollections)
|
||||
);
|
||||
}
|
||||
|
||||
get canEditAnyCollection() {
|
||||
return (
|
||||
this.isAdmin || (this.permissions.editAnyCollection ?? this.permissions.manageAllCollections)
|
||||
);
|
||||
}
|
||||
|
||||
get canDeleteAnyCollection() {
|
||||
return (
|
||||
this.isAdmin ||
|
||||
(this.permissions.deleteAnyCollection ?? this.permissions.manageAllCollections)
|
||||
);
|
||||
}
|
||||
|
||||
get canViewAllCollections() {
|
||||
return this.canCreateNewCollections || this.canEditAnyCollection || this.canDeleteAnyCollection;
|
||||
}
|
||||
|
||||
get canEditAssignedCollections() {
|
||||
return (
|
||||
this.isManager ||
|
||||
(this.permissions.editAssignedCollections ?? this.permissions.manageAssignedCollections)
|
||||
);
|
||||
}
|
||||
|
||||
get canDeleteAssignedCollections() {
|
||||
return (
|
||||
this.isManager ||
|
||||
(this.permissions.deleteAssignedCollections ?? this.permissions.manageAssignedCollections)
|
||||
);
|
||||
}
|
||||
|
||||
get canViewAssignedCollections() {
|
||||
return this.canDeleteAssignedCollections || this.canEditAssignedCollections;
|
||||
}
|
||||
|
||||
get canManageGroups() {
|
||||
return this.isAdmin || this.permissions.manageGroups;
|
||||
}
|
||||
|
||||
get canManageSso() {
|
||||
return this.isAdmin || this.permissions.manageSso;
|
||||
}
|
||||
|
||||
get canManagePolicies() {
|
||||
return this.isAdmin || this.permissions.managePolicies;
|
||||
}
|
||||
|
||||
get canManageUsers() {
|
||||
return this.isAdmin || this.permissions.manageUsers;
|
||||
}
|
||||
|
||||
get canManageUsersPassword() {
|
||||
return this.isAdmin || this.permissions.manageResetPassword;
|
||||
}
|
||||
|
||||
get isExemptFromPolicies() {
|
||||
return this.canManagePolicies;
|
||||
}
|
||||
}
|
||||
@@ -1,50 +0,0 @@
|
||||
import { ProviderUserStatusType } from "../../enums/providerUserStatusType";
|
||||
import { ProviderUserType } from "../../enums/providerUserType";
|
||||
import { ProviderData } from "../data/providerData";
|
||||
|
||||
export class Provider {
|
||||
id: string;
|
||||
name: string;
|
||||
status: ProviderUserStatusType;
|
||||
type: ProviderUserType;
|
||||
enabled: boolean;
|
||||
userId: string;
|
||||
useEvents: boolean;
|
||||
|
||||
constructor(obj?: ProviderData) {
|
||||
if (obj == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
this.id = obj.id;
|
||||
this.name = obj.name;
|
||||
this.status = obj.status;
|
||||
this.type = obj.type;
|
||||
this.enabled = obj.enabled;
|
||||
this.userId = obj.userId;
|
||||
this.useEvents = obj.useEvents;
|
||||
}
|
||||
|
||||
get canAccess() {
|
||||
if (this.isProviderAdmin) {
|
||||
return true;
|
||||
}
|
||||
return this.enabled && this.status === ProviderUserStatusType.Confirmed;
|
||||
}
|
||||
|
||||
get canCreateOrganizations() {
|
||||
return this.enabled && this.isProviderAdmin;
|
||||
}
|
||||
|
||||
get canManageUsers() {
|
||||
return this.isProviderAdmin;
|
||||
}
|
||||
|
||||
get canAccessEventLogs() {
|
||||
return this.isProviderAdmin;
|
||||
}
|
||||
|
||||
get isProviderAdmin() {
|
||||
return this.type === ProviderUserType.ProviderAdmin;
|
||||
}
|
||||
}
|
||||
@@ -1,16 +0,0 @@
|
||||
export class TreeNode<T extends ITreeNodeObject> {
|
||||
parent: T;
|
||||
node: T;
|
||||
children: TreeNode<T>[] = [];
|
||||
|
||||
constructor(node: T, name: string, parent: T) {
|
||||
this.parent = parent;
|
||||
this.node = node;
|
||||
this.node.name = name;
|
||||
}
|
||||
}
|
||||
|
||||
export interface ITreeNodeObject {
|
||||
id: string;
|
||||
name: string;
|
||||
}
|
||||
@@ -1,10 +0,0 @@
|
||||
import { BaseResponse } from "./baseResponse";
|
||||
|
||||
export class ApiKeyResponse extends BaseResponse {
|
||||
apiKey: string;
|
||||
|
||||
constructor(response: any) {
|
||||
super(response);
|
||||
this.apiKey = this.getResponseProperty("ApiKey");
|
||||
}
|
||||
}
|
||||
@@ -1,83 +0,0 @@
|
||||
import { PaymentMethodType } from "../../enums/paymentMethodType";
|
||||
import { TransactionType } from "../../enums/transactionType";
|
||||
|
||||
import { BaseResponse } from "./baseResponse";
|
||||
|
||||
export class BillingResponse extends BaseResponse {
|
||||
balance: number;
|
||||
paymentSource: BillingSourceResponse;
|
||||
invoices: BillingInvoiceResponse[] = [];
|
||||
transactions: BillingTransactionResponse[] = [];
|
||||
|
||||
constructor(response: any) {
|
||||
super(response);
|
||||
this.balance = this.getResponseProperty("Balance");
|
||||
const paymentSource = this.getResponseProperty("PaymentSource");
|
||||
const transactions = this.getResponseProperty("Transactions");
|
||||
const invoices = this.getResponseProperty("Invoices");
|
||||
this.paymentSource = paymentSource == null ? null : new BillingSourceResponse(paymentSource);
|
||||
if (transactions != null) {
|
||||
this.transactions = transactions.map((t: any) => new BillingTransactionResponse(t));
|
||||
}
|
||||
if (invoices != null) {
|
||||
this.invoices = invoices.map((i: any) => new BillingInvoiceResponse(i));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
export class BillingSourceResponse extends BaseResponse {
|
||||
type: PaymentMethodType;
|
||||
cardBrand: string;
|
||||
description: string;
|
||||
needsVerification: boolean;
|
||||
|
||||
constructor(response: any) {
|
||||
super(response);
|
||||
this.type = this.getResponseProperty("Type");
|
||||
this.cardBrand = this.getResponseProperty("CardBrand");
|
||||
this.description = this.getResponseProperty("Description");
|
||||
this.needsVerification = this.getResponseProperty("NeedsVerification");
|
||||
}
|
||||
}
|
||||
|
||||
export class BillingInvoiceResponse extends BaseResponse {
|
||||
url: string;
|
||||
pdfUrl: string;
|
||||
number: string;
|
||||
paid: boolean;
|
||||
date: string;
|
||||
amount: number;
|
||||
|
||||
constructor(response: any) {
|
||||
super(response);
|
||||
this.url = this.getResponseProperty("Url");
|
||||
this.pdfUrl = this.getResponseProperty("PdfUrl");
|
||||
this.number = this.getResponseProperty("Number");
|
||||
this.paid = this.getResponseProperty("Paid");
|
||||
this.date = this.getResponseProperty("Date");
|
||||
this.amount = this.getResponseProperty("Amount");
|
||||
}
|
||||
}
|
||||
|
||||
export class BillingTransactionResponse extends BaseResponse {
|
||||
createdDate: string;
|
||||
amount: number;
|
||||
refunded: boolean;
|
||||
partiallyRefunded: boolean;
|
||||
refundedAmount: number;
|
||||
type: TransactionType;
|
||||
paymentMethodType: PaymentMethodType;
|
||||
details: string;
|
||||
|
||||
constructor(response: any) {
|
||||
super(response);
|
||||
this.createdDate = this.getResponseProperty("CreatedDate");
|
||||
this.amount = this.getResponseProperty("Amount");
|
||||
this.refunded = this.getResponseProperty("Refunded");
|
||||
this.partiallyRefunded = this.getResponseProperty("PartiallyRefunded");
|
||||
this.refundedAmount = this.getResponseProperty("RefundedAmount");
|
||||
this.type = this.getResponseProperty("Type");
|
||||
this.paymentMethodType = this.getResponseProperty("PaymentMethodType");
|
||||
this.details = this.getResponseProperty("Details");
|
||||
}
|
||||
}
|
||||
@@ -1,32 +0,0 @@
|
||||
import { BaseResponse } from "./baseResponse";
|
||||
|
||||
export class BreachAccountResponse extends BaseResponse {
|
||||
addedDate: string;
|
||||
breachDate: string;
|
||||
dataClasses: string[];
|
||||
description: string;
|
||||
domain: string;
|
||||
isActive: boolean;
|
||||
isVerified: boolean;
|
||||
logoPath: string;
|
||||
modifiedDate: string;
|
||||
name: string;
|
||||
pwnCount: number;
|
||||
title: string;
|
||||
|
||||
constructor(response: any) {
|
||||
super(response);
|
||||
this.addedDate = this.getResponseProperty("AddedDate");
|
||||
this.breachDate = this.getResponseProperty("BreachDate");
|
||||
this.dataClasses = this.getResponseProperty("DataClasses");
|
||||
this.description = this.getResponseProperty("Description");
|
||||
this.domain = this.getResponseProperty("Domain");
|
||||
this.isActive = this.getResponseProperty("IsActive");
|
||||
this.isVerified = this.getResponseProperty("IsVerified");
|
||||
this.logoPath = this.getResponseProperty("LogoPath");
|
||||
this.modifiedDate = this.getResponseProperty("ModifiedDate");
|
||||
this.name = this.getResponseProperty("Name");
|
||||
this.pwnCount = this.getResponseProperty("PwnCount");
|
||||
this.title = this.getResponseProperty("Title");
|
||||
}
|
||||
}
|
||||
@@ -1,20 +0,0 @@
|
||||
import { DeviceType } from "../../enums/deviceType";
|
||||
|
||||
import { BaseResponse } from "./baseResponse";
|
||||
|
||||
export class DeviceResponse extends BaseResponse {
|
||||
id: string;
|
||||
name: number;
|
||||
identifier: string;
|
||||
type: DeviceType;
|
||||
creationDate: string;
|
||||
|
||||
constructor(response: any) {
|
||||
super(response);
|
||||
this.id = this.getResponseProperty("Id");
|
||||
this.name = this.getResponseProperty("Name");
|
||||
this.identifier = this.getResponseProperty("Identifier");
|
||||
this.type = this.getResponseProperty("Type");
|
||||
this.creationDate = this.getResponseProperty("CreationDate");
|
||||
}
|
||||
}
|
||||
@@ -1,20 +0,0 @@
|
||||
import { BaseResponse } from "./baseResponse";
|
||||
import { GlobalDomainResponse } from "./globalDomainResponse";
|
||||
|
||||
export class DomainsResponse extends BaseResponse {
|
||||
equivalentDomains: string[][];
|
||||
globalEquivalentDomains: GlobalDomainResponse[] = [];
|
||||
|
||||
constructor(response: any) {
|
||||
super(response);
|
||||
this.equivalentDomains = this.getResponseProperty("EquivalentDomains");
|
||||
const globalEquivalentDomains = this.getResponseProperty("GlobalEquivalentDomains");
|
||||
if (globalEquivalentDomains != null) {
|
||||
this.globalEquivalentDomains = globalEquivalentDomains.map(
|
||||
(d: any) => new GlobalDomainResponse(d),
|
||||
);
|
||||
} else {
|
||||
this.globalEquivalentDomains = [];
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,14 +0,0 @@
|
||||
import { BaseResponse } from "./baseResponse";
|
||||
|
||||
export class GlobalDomainResponse extends BaseResponse {
|
||||
type: number;
|
||||
domains: string[];
|
||||
excluded: boolean;
|
||||
|
||||
constructor(response: any) {
|
||||
super(response);
|
||||
this.type = this.getResponseProperty("Type");
|
||||
this.domains = this.getResponseProperty("Domains");
|
||||
this.excluded = this.getResponseProperty("Excluded");
|
||||
}
|
||||
}
|
||||
@@ -1,31 +0,0 @@
|
||||
import { BaseResponse } from "./baseResponse";
|
||||
import { SelectionReadOnlyResponse } from "./selectionReadOnlyResponse";
|
||||
|
||||
export class GroupResponse extends BaseResponse {
|
||||
id: string;
|
||||
organizationId: string;
|
||||
name: string;
|
||||
accessAll: boolean;
|
||||
externalId: string;
|
||||
|
||||
constructor(response: any) {
|
||||
super(response);
|
||||
this.id = this.getResponseProperty("Id");
|
||||
this.organizationId = this.getResponseProperty("OrganizationId");
|
||||
this.name = this.getResponseProperty("Name");
|
||||
this.accessAll = this.getResponseProperty("AccessAll");
|
||||
this.externalId = this.getResponseProperty("ExternalId");
|
||||
}
|
||||
}
|
||||
|
||||
export class GroupDetailsResponse extends GroupResponse {
|
||||
collections: SelectionReadOnlyResponse[] = [];
|
||||
|
||||
constructor(response: any) {
|
||||
super(response);
|
||||
const collections = this.getResponseProperty("Collections");
|
||||
if (collections != null) {
|
||||
this.collections = collections.map((c: any) => new SelectionReadOnlyResponse(c));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,10 +0,0 @@
|
||||
import { BaseResponse } from "./baseResponse";
|
||||
|
||||
export class KeyConnectorUserKeyResponse extends BaseResponse {
|
||||
key: string;
|
||||
|
||||
constructor(response: any) {
|
||||
super(response);
|
||||
this.key = this.getResponseProperty("Key");
|
||||
}
|
||||
}
|
||||
@@ -1,12 +0,0 @@
|
||||
import { BaseResponse } from "./baseResponse";
|
||||
|
||||
export class KeysResponse extends BaseResponse {
|
||||
privateKey: string;
|
||||
publicKey: string;
|
||||
|
||||
constructor(response: any) {
|
||||
super(response);
|
||||
this.privateKey = this.getResponseProperty("PrivateKey");
|
||||
this.publicKey = this.getResponseProperty("PublicKey");
|
||||
}
|
||||
}
|
||||
@@ -1,13 +0,0 @@
|
||||
import { BaseResponse } from "./baseResponse";
|
||||
|
||||
export class ListResponse<T> extends BaseResponse {
|
||||
data: T[];
|
||||
continuationToken: string;
|
||||
|
||||
constructor(response: any, t: new (dataResponse: any) => T) {
|
||||
super(response);
|
||||
const data = this.getResponseProperty("Data");
|
||||
this.data = data == null ? [] : data.map((dr: any) => new t(dr));
|
||||
this.continuationToken = this.getResponseProperty("ContinuationToken");
|
||||
}
|
||||
}
|
||||
@@ -1,98 +0,0 @@
|
||||
import { NotificationType } from "../../enums/notificationType";
|
||||
|
||||
import { BaseResponse } from "./baseResponse";
|
||||
|
||||
export class NotificationResponse extends BaseResponse {
|
||||
contextId: string;
|
||||
type: NotificationType;
|
||||
payload: any;
|
||||
|
||||
constructor(response: any) {
|
||||
super(response);
|
||||
this.contextId = this.getResponseProperty("ContextId");
|
||||
this.type = this.getResponseProperty("Type");
|
||||
|
||||
const payload = this.getResponseProperty("Payload");
|
||||
switch (this.type) {
|
||||
case NotificationType.SyncCipherCreate:
|
||||
case NotificationType.SyncCipherDelete:
|
||||
case NotificationType.SyncCipherUpdate:
|
||||
case NotificationType.SyncLoginDelete:
|
||||
this.payload = new SyncCipherNotification(payload);
|
||||
break;
|
||||
case NotificationType.SyncFolderCreate:
|
||||
case NotificationType.SyncFolderDelete:
|
||||
case NotificationType.SyncFolderUpdate:
|
||||
this.payload = new SyncFolderNotification(payload);
|
||||
break;
|
||||
case NotificationType.SyncVault:
|
||||
case NotificationType.SyncCiphers:
|
||||
case NotificationType.SyncOrgKeys:
|
||||
case NotificationType.SyncSettings:
|
||||
case NotificationType.LogOut:
|
||||
this.payload = new UserNotification(payload);
|
||||
break;
|
||||
case NotificationType.SyncSendCreate:
|
||||
case NotificationType.SyncSendUpdate:
|
||||
case NotificationType.SyncSendDelete:
|
||||
this.payload = new SyncSendNotification(payload);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
export class SyncCipherNotification extends BaseResponse {
|
||||
id: string;
|
||||
userId: string;
|
||||
organizationId: string;
|
||||
collectionIds: string[];
|
||||
revisionDate: Date;
|
||||
|
||||
constructor(response: any) {
|
||||
super(response);
|
||||
this.id = this.getResponseProperty("Id");
|
||||
this.userId = this.getResponseProperty("UserId");
|
||||
this.organizationId = this.getResponseProperty("OrganizationId");
|
||||
this.collectionIds = this.getResponseProperty("CollectionIds");
|
||||
this.revisionDate = new Date(this.getResponseProperty("RevisionDate"));
|
||||
}
|
||||
}
|
||||
|
||||
export class SyncFolderNotification extends BaseResponse {
|
||||
id: string;
|
||||
userId: string;
|
||||
revisionDate: Date;
|
||||
|
||||
constructor(response: any) {
|
||||
super(response);
|
||||
this.id = this.getResponseProperty("Id");
|
||||
this.userId = this.getResponseProperty("UserId");
|
||||
this.revisionDate = new Date(this.getResponseProperty("RevisionDate"));
|
||||
}
|
||||
}
|
||||
|
||||
export class UserNotification extends BaseResponse {
|
||||
userId: string;
|
||||
date: Date;
|
||||
|
||||
constructor(response: any) {
|
||||
super(response);
|
||||
this.userId = this.getResponseProperty("UserId");
|
||||
this.date = new Date(this.getResponseProperty("Date"));
|
||||
}
|
||||
}
|
||||
|
||||
export class SyncSendNotification extends BaseResponse {
|
||||
id: string;
|
||||
userId: string;
|
||||
revisionDate: Date;
|
||||
|
||||
constructor(response: any) {
|
||||
super(response);
|
||||
this.id = this.getResponseProperty("Id");
|
||||
this.userId = this.getResponseProperty("UserId");
|
||||
this.revisionDate = new Date(this.getResponseProperty("RevisionDate"));
|
||||
}
|
||||
}
|
||||
@@ -1,35 +0,0 @@
|
||||
import { SsoConfigApi } from "../../api/ssoConfigApi";
|
||||
import { BaseResponse } from "../baseResponse";
|
||||
|
||||
export class OrganizationSsoResponse extends BaseResponse {
|
||||
enabled: boolean;
|
||||
data: SsoConfigApi;
|
||||
urls: SsoUrls;
|
||||
|
||||
constructor(response: any) {
|
||||
super(response);
|
||||
this.enabled = this.getResponseProperty("Enabled");
|
||||
this.data =
|
||||
this.getResponseProperty("Data") != null
|
||||
? new SsoConfigApi(this.getResponseProperty("Data"))
|
||||
: null;
|
||||
this.urls = new SsoUrls(this.getResponseProperty("Urls"));
|
||||
}
|
||||
}
|
||||
|
||||
class SsoUrls extends BaseResponse {
|
||||
callbackPath: string;
|
||||
signedOutCallbackPath: string;
|
||||
spEntityId: string;
|
||||
spMetadataUrl: string;
|
||||
spAcsUrl: string;
|
||||
|
||||
constructor(response: any) {
|
||||
super(response);
|
||||
this.callbackPath = this.getResponseProperty("CallbackPath");
|
||||
this.signedOutCallbackPath = this.getResponseProperty("SignedOutCallbackPath");
|
||||
this.spEntityId = this.getResponseProperty("SpEntityId");
|
||||
this.spMetadataUrl = this.getResponseProperty("SpMetadataUrl");
|
||||
this.spAcsUrl = this.getResponseProperty("SpAcsUrl");
|
||||
}
|
||||
}
|
||||
@@ -1,12 +0,0 @@
|
||||
import { BaseResponse } from "./baseResponse";
|
||||
|
||||
export class OrganizationAutoEnrollStatusResponse extends BaseResponse {
|
||||
id: string;
|
||||
resetPasswordEnabled: boolean;
|
||||
|
||||
constructor(response: any) {
|
||||
super(response);
|
||||
this.id = this.getResponseProperty("Id");
|
||||
this.resetPasswordEnabled = this.getResponseProperty("ResetPasswordEnabled");
|
||||
}
|
||||
}
|
||||
@@ -1,7 +0,0 @@
|
||||
import { KeysResponse } from "./keysResponse";
|
||||
|
||||
export class OrganizationKeysResponse extends KeysResponse {
|
||||
constructor(response: any) {
|
||||
super(response);
|
||||
}
|
||||
}
|
||||
@@ -1,60 +0,0 @@
|
||||
import { PlanType } from "../../enums/planType";
|
||||
|
||||
import { BaseResponse } from "./baseResponse";
|
||||
import { PlanResponse } from "./planResponse";
|
||||
|
||||
export class OrganizationResponse extends BaseResponse {
|
||||
id: string;
|
||||
identifier: string;
|
||||
name: string;
|
||||
businessName: string;
|
||||
businessAddress1: string;
|
||||
businessAddress2: string;
|
||||
businessAddress3: string;
|
||||
businessCountry: string;
|
||||
businessTaxNumber: string;
|
||||
billingEmail: string;
|
||||
plan: PlanResponse;
|
||||
planType: PlanType;
|
||||
seats: number;
|
||||
maxAutoscaleSeats: number;
|
||||
maxCollections: number;
|
||||
maxStorageGb: number;
|
||||
useGroups: boolean;
|
||||
useDirectory: boolean;
|
||||
useEvents: boolean;
|
||||
useTotp: boolean;
|
||||
use2fa: boolean;
|
||||
useApi: boolean;
|
||||
useResetPassword: boolean;
|
||||
hasPublicAndPrivateKeys: boolean;
|
||||
|
||||
constructor(response: any) {
|
||||
super(response);
|
||||
this.id = this.getResponseProperty("Id");
|
||||
this.identifier = this.getResponseProperty("Identifier");
|
||||
this.name = this.getResponseProperty("Name");
|
||||
this.businessName = this.getResponseProperty("BusinessName");
|
||||
this.businessAddress1 = this.getResponseProperty("BusinessAddress1");
|
||||
this.businessAddress2 = this.getResponseProperty("BusinessAddress2");
|
||||
this.businessAddress3 = this.getResponseProperty("BusinessAddress3");
|
||||
this.businessCountry = this.getResponseProperty("BusinessCountry");
|
||||
this.businessTaxNumber = this.getResponseProperty("BusinessTaxNumber");
|
||||
this.billingEmail = this.getResponseProperty("BillingEmail");
|
||||
const plan = this.getResponseProperty("Plan");
|
||||
this.plan = plan == null ? null : new PlanResponse(plan);
|
||||
this.planType = this.getResponseProperty("PlanType");
|
||||
this.seats = this.getResponseProperty("Seats");
|
||||
this.maxAutoscaleSeats = this.getResponseProperty("MaxAutoscaleSeats");
|
||||
this.maxCollections = this.getResponseProperty("MaxCollections");
|
||||
this.maxStorageGb = this.getResponseProperty("MaxStorageGb");
|
||||
this.useGroups = this.getResponseProperty("UseGroups");
|
||||
this.useDirectory = this.getResponseProperty("UseDirectory");
|
||||
this.useEvents = this.getResponseProperty("UseEvents");
|
||||
this.useTotp = this.getResponseProperty("UseTotp");
|
||||
this.use2fa = this.getResponseProperty("Use2fa");
|
||||
this.useApi = this.getResponseProperty("UseApi");
|
||||
this.useResetPassword = this.getResponseProperty("UseResetPassword");
|
||||
this.hasPublicAndPrivateKeys = this.getResponseProperty("HasPublicAndPrivateKeys");
|
||||
}
|
||||
}
|
||||
@@ -1,27 +0,0 @@
|
||||
import { OrganizationResponse } from "./organizationResponse";
|
||||
import {
|
||||
BillingSubscriptionResponse,
|
||||
BillingSubscriptionUpcomingInvoiceResponse,
|
||||
} from "./subscriptionResponse";
|
||||
|
||||
export class OrganizationSubscriptionResponse extends OrganizationResponse {
|
||||
storageName: string;
|
||||
storageGb: number;
|
||||
subscription: BillingSubscriptionResponse;
|
||||
upcomingInvoice: BillingSubscriptionUpcomingInvoiceResponse;
|
||||
expiration: string;
|
||||
|
||||
constructor(response: any) {
|
||||
super(response);
|
||||
this.storageName = this.getResponseProperty("StorageName");
|
||||
this.storageGb = this.getResponseProperty("StorageGb");
|
||||
const subscription = this.getResponseProperty("Subscription");
|
||||
this.subscription = subscription == null ? null : new BillingSubscriptionResponse(subscription);
|
||||
const upcomingInvoice = this.getResponseProperty("UpcomingInvoice");
|
||||
this.upcomingInvoice =
|
||||
upcomingInvoice == null
|
||||
? null
|
||||
: new BillingSubscriptionUpcomingInvoiceResponse(upcomingInvoice);
|
||||
this.expiration = this.getResponseProperty("Expiration");
|
||||
}
|
||||
}
|
||||
@@ -1,14 +0,0 @@
|
||||
import { BaseResponse } from "./baseResponse";
|
||||
|
||||
export class OrganizationUserBulkPublicKeyResponse extends BaseResponse {
|
||||
id: string;
|
||||
userId: string;
|
||||
key: string;
|
||||
|
||||
constructor(response: any) {
|
||||
super(response);
|
||||
this.id = this.getResponseProperty("Id");
|
||||
this.userId = this.getResponseProperty("UserId");
|
||||
this.key = this.getResponseProperty("Key");
|
||||
}
|
||||
}
|
||||
@@ -1,12 +0,0 @@
|
||||
import { BaseResponse } from "./baseResponse";
|
||||
|
||||
export class OrganizationUserBulkResponse extends BaseResponse {
|
||||
id: string;
|
||||
error: string;
|
||||
|
||||
constructor(response: any) {
|
||||
super(response);
|
||||
this.id = this.getResponseProperty("Id");
|
||||
this.error = this.getResponseProperty("Error");
|
||||
}
|
||||
}
|
||||
@@ -1,70 +0,0 @@
|
||||
import { KdfType } from "../../enums/kdfType";
|
||||
import { OrganizationUserStatusType } from "../../enums/organizationUserStatusType";
|
||||
import { OrganizationUserType } from "../../enums/organizationUserType";
|
||||
import { PermissionsApi } from "../api/permissionsApi";
|
||||
|
||||
import { BaseResponse } from "./baseResponse";
|
||||
import { SelectionReadOnlyResponse } from "./selectionReadOnlyResponse";
|
||||
|
||||
export class OrganizationUserResponse extends BaseResponse {
|
||||
id: string;
|
||||
userId: string;
|
||||
type: OrganizationUserType;
|
||||
status: OrganizationUserStatusType;
|
||||
accessAll: boolean;
|
||||
permissions: PermissionsApi;
|
||||
resetPasswordEnrolled: boolean;
|
||||
|
||||
constructor(response: any) {
|
||||
super(response);
|
||||
this.id = this.getResponseProperty("Id");
|
||||
this.userId = this.getResponseProperty("UserId");
|
||||
this.type = this.getResponseProperty("Type");
|
||||
this.status = this.getResponseProperty("Status");
|
||||
this.permissions = new PermissionsApi(this.getResponseProperty("Permissions"));
|
||||
this.accessAll = this.getResponseProperty("AccessAll");
|
||||
this.resetPasswordEnrolled = this.getResponseProperty("ResetPasswordEnrolled");
|
||||
}
|
||||
}
|
||||
|
||||
export class OrganizationUserUserDetailsResponse extends OrganizationUserResponse {
|
||||
name: string;
|
||||
email: string;
|
||||
twoFactorEnabled: boolean;
|
||||
usesKeyConnector: boolean;
|
||||
|
||||
constructor(response: any) {
|
||||
super(response);
|
||||
this.name = this.getResponseProperty("Name");
|
||||
this.email = this.getResponseProperty("Email");
|
||||
this.twoFactorEnabled = this.getResponseProperty("TwoFactorEnabled");
|
||||
this.usesKeyConnector = this.getResponseProperty("UsesKeyConnector") ?? false;
|
||||
}
|
||||
}
|
||||
|
||||
export class OrganizationUserDetailsResponse extends OrganizationUserResponse {
|
||||
collections: SelectionReadOnlyResponse[] = [];
|
||||
|
||||
constructor(response: any) {
|
||||
super(response);
|
||||
const collections = this.getResponseProperty("Collections");
|
||||
if (collections != null) {
|
||||
this.collections = collections.map((c: any) => new SelectionReadOnlyResponse(c));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
export class OrganizationUserResetPasswordDetailsReponse extends BaseResponse {
|
||||
kdf: KdfType;
|
||||
kdfIterations: number;
|
||||
resetPasswordKey: string;
|
||||
encryptedPrivateKey: string;
|
||||
|
||||
constructor(response: any) {
|
||||
super(response);
|
||||
this.kdf = this.getResponseProperty("Kdf");
|
||||
this.kdfIterations = this.getResponseProperty("KdfIterations");
|
||||
this.resetPasswordKey = this.getResponseProperty("ResetPasswordKey");
|
||||
this.encryptedPrivateKey = this.getResponseProperty("EncryptedPrivateKey");
|
||||
}
|
||||
}
|
||||
@@ -1,18 +0,0 @@
|
||||
import { BaseResponse } from "./baseResponse";
|
||||
import { ProfileResponse } from "./profileResponse";
|
||||
|
||||
export class PaymentResponse extends BaseResponse {
|
||||
userProfile: ProfileResponse;
|
||||
paymentIntentClientSecret: string;
|
||||
success: boolean;
|
||||
|
||||
constructor(response: any) {
|
||||
super(response);
|
||||
const userProfile = this.getResponseProperty("UserProfile");
|
||||
if (userProfile != null) {
|
||||
this.userProfile = new ProfileResponse(userProfile);
|
||||
}
|
||||
this.paymentIntentClientSecret = this.getResponseProperty("PaymentIntentClientSecret");
|
||||
this.success = this.getResponseProperty("Success");
|
||||
}
|
||||
}
|
||||
@@ -1,95 +0,0 @@
|
||||
import { PlanType } from "../../enums/planType";
|
||||
import { ProductType } from "../../enums/productType";
|
||||
|
||||
import { BaseResponse } from "./baseResponse";
|
||||
|
||||
export class PlanResponse extends BaseResponse {
|
||||
type: PlanType;
|
||||
product: ProductType;
|
||||
name: string;
|
||||
isAnnual: boolean;
|
||||
nameLocalizationKey: string;
|
||||
descriptionLocalizationKey: string;
|
||||
canBeUsedByBusiness: boolean;
|
||||
baseSeats: number;
|
||||
baseStorageGb: number;
|
||||
maxCollections: number;
|
||||
maxUsers: number;
|
||||
|
||||
hasAdditionalSeatsOption: boolean;
|
||||
maxAdditionalSeats: number;
|
||||
hasAdditionalStorageOption: boolean;
|
||||
maxAdditionalStorage: number;
|
||||
hasPremiumAccessOption: boolean;
|
||||
trialPeriodDays: number;
|
||||
|
||||
hasSelfHost: boolean;
|
||||
hasPolicies: boolean;
|
||||
hasGroups: boolean;
|
||||
hasDirectory: boolean;
|
||||
hasEvents: boolean;
|
||||
hasTotp: boolean;
|
||||
has2fa: boolean;
|
||||
hasApi: boolean;
|
||||
hasSso: boolean;
|
||||
hasResetPassword: boolean;
|
||||
usersGetPremium: boolean;
|
||||
|
||||
upgradeSortOrder: number;
|
||||
displaySortOrder: number;
|
||||
legacyYear: number;
|
||||
disabled: boolean;
|
||||
|
||||
stripePlanId: string;
|
||||
stripeSeatPlanId: string;
|
||||
stripeStoragePlanId: string;
|
||||
stripePremiumAccessPlanId: string;
|
||||
basePrice: number;
|
||||
seatPrice: number;
|
||||
additionalStoragePricePerGb: number;
|
||||
premiumAccessOptionPrice: number;
|
||||
|
||||
constructor(response: any) {
|
||||
super(response);
|
||||
this.type = this.getResponseProperty("Type");
|
||||
this.product = this.getResponseProperty("Product");
|
||||
this.name = this.getResponseProperty("Name");
|
||||
this.isAnnual = this.getResponseProperty("IsAnnual");
|
||||
this.nameLocalizationKey = this.getResponseProperty("NameLocalizationKey");
|
||||
this.descriptionLocalizationKey = this.getResponseProperty("DescriptionLocalizationKey");
|
||||
this.canBeUsedByBusiness = this.getResponseProperty("CanBeUsedByBusiness");
|
||||
this.baseSeats = this.getResponseProperty("BaseSeats");
|
||||
this.baseStorageGb = this.getResponseProperty("BaseStorageGb");
|
||||
this.maxCollections = this.getResponseProperty("MaxCollections");
|
||||
this.maxUsers = this.getResponseProperty("MaxUsers");
|
||||
this.hasAdditionalSeatsOption = this.getResponseProperty("HasAdditionalSeatsOption");
|
||||
this.maxAdditionalSeats = this.getResponseProperty("MaxAdditionalSeats");
|
||||
this.hasAdditionalStorageOption = this.getResponseProperty("HasAdditionalStorageOption");
|
||||
this.maxAdditionalStorage = this.getResponseProperty("MaxAdditionalStorage");
|
||||
this.hasPremiumAccessOption = this.getResponseProperty("HasPremiumAccessOption");
|
||||
this.trialPeriodDays = this.getResponseProperty("TrialPeriodDays");
|
||||
this.hasSelfHost = this.getResponseProperty("HasSelfHost");
|
||||
this.hasPolicies = this.getResponseProperty("HasPolicies");
|
||||
this.hasGroups = this.getResponseProperty("HasGroups");
|
||||
this.hasDirectory = this.getResponseProperty("HasDirectory");
|
||||
this.hasEvents = this.getResponseProperty("HasEvents");
|
||||
this.hasTotp = this.getResponseProperty("HasTotp");
|
||||
this.has2fa = this.getResponseProperty("Has2fa");
|
||||
this.hasApi = this.getResponseProperty("HasApi");
|
||||
this.hasSso = this.getResponseProperty("HasSso");
|
||||
this.hasResetPassword = this.getResponseProperty("HasResetPassword");
|
||||
this.usersGetPremium = this.getResponseProperty("UsersGetPremium");
|
||||
this.upgradeSortOrder = this.getResponseProperty("UpgradeSortOrder");
|
||||
this.displaySortOrder = this.getResponseProperty("SortOrder");
|
||||
this.legacyYear = this.getResponseProperty("LegacyYear");
|
||||
this.disabled = this.getResponseProperty("Disabled");
|
||||
this.stripePlanId = this.getResponseProperty("StripePlanId");
|
||||
this.stripeSeatPlanId = this.getResponseProperty("StripeSeatPlanId");
|
||||
this.stripeStoragePlanId = this.getResponseProperty("StripeStoragePlanId");
|
||||
this.stripePremiumAccessPlanId = this.getResponseProperty("StripePremiumAccessPlanId");
|
||||
this.basePrice = this.getResponseProperty("BasePrice");
|
||||
this.seatPrice = this.getResponseProperty("SeatPrice");
|
||||
this.additionalStoragePricePerGb = this.getResponseProperty("AdditionalStoragePricePerGb");
|
||||
this.premiumAccessOptionPrice = this.getResponseProperty("PremiumAccessOptionPrice");
|
||||
}
|
||||
}
|
||||
@@ -1,14 +0,0 @@
|
||||
import { KdfType } from "../../enums/kdfType";
|
||||
|
||||
import { BaseResponse } from "./baseResponse";
|
||||
|
||||
export class PreloginResponse extends BaseResponse {
|
||||
kdf: KdfType;
|
||||
kdfIterations: number;
|
||||
|
||||
constructor(response: any) {
|
||||
super(response);
|
||||
this.kdf = this.getResponseProperty("Kdf");
|
||||
this.kdfIterations = this.getResponseProperty("KdfIterations");
|
||||
}
|
||||
}
|
||||
@@ -1,81 +0,0 @@
|
||||
import { OrganizationUserStatusType } from "../../enums/organizationUserStatusType";
|
||||
import { OrganizationUserType } from "../../enums/organizationUserType";
|
||||
import { ProductType } from "../../enums/productType";
|
||||
import { PermissionsApi } from "../api/permissionsApi";
|
||||
|
||||
import { BaseResponse } from "./baseResponse";
|
||||
|
||||
export class ProfileOrganizationResponse extends BaseResponse {
|
||||
id: string;
|
||||
name: string;
|
||||
usePolicies: boolean;
|
||||
useGroups: boolean;
|
||||
useDirectory: boolean;
|
||||
useEvents: boolean;
|
||||
useTotp: boolean;
|
||||
use2fa: boolean;
|
||||
useApi: boolean;
|
||||
useSso: boolean;
|
||||
useKeyConnector: boolean;
|
||||
useResetPassword: boolean;
|
||||
selfHost: boolean;
|
||||
usersGetPremium: boolean;
|
||||
seats: number;
|
||||
maxCollections: number;
|
||||
maxStorageGb?: number;
|
||||
key: string;
|
||||
hasPublicAndPrivateKeys: boolean;
|
||||
status: OrganizationUserStatusType;
|
||||
type: OrganizationUserType;
|
||||
enabled: boolean;
|
||||
ssoBound: boolean;
|
||||
identifier: string;
|
||||
permissions: PermissionsApi;
|
||||
resetPasswordEnrolled: boolean;
|
||||
userId: string;
|
||||
providerId: string;
|
||||
providerName: string;
|
||||
familySponsorshipFriendlyName: string;
|
||||
familySponsorshipAvailable: boolean;
|
||||
planProductType: ProductType;
|
||||
keyConnectorEnabled: boolean;
|
||||
keyConnectorUrl: string;
|
||||
|
||||
constructor(response: any) {
|
||||
super(response);
|
||||
this.id = this.getResponseProperty("Id");
|
||||
this.name = this.getResponseProperty("Name");
|
||||
this.usePolicies = this.getResponseProperty("UsePolicies");
|
||||
this.useGroups = this.getResponseProperty("UseGroups");
|
||||
this.useDirectory = this.getResponseProperty("UseDirectory");
|
||||
this.useEvents = this.getResponseProperty("UseEvents");
|
||||
this.useTotp = this.getResponseProperty("UseTotp");
|
||||
this.use2fa = this.getResponseProperty("Use2fa");
|
||||
this.useApi = this.getResponseProperty("UseApi");
|
||||
this.useSso = this.getResponseProperty("UseSso");
|
||||
this.useKeyConnector = this.getResponseProperty("UseKeyConnector") ?? false;
|
||||
this.useResetPassword = this.getResponseProperty("UseResetPassword");
|
||||
this.selfHost = this.getResponseProperty("SelfHost");
|
||||
this.usersGetPremium = this.getResponseProperty("UsersGetPremium");
|
||||
this.seats = this.getResponseProperty("Seats");
|
||||
this.maxCollections = this.getResponseProperty("MaxCollections");
|
||||
this.maxStorageGb = this.getResponseProperty("MaxStorageGb");
|
||||
this.key = this.getResponseProperty("Key");
|
||||
this.hasPublicAndPrivateKeys = this.getResponseProperty("HasPublicAndPrivateKeys");
|
||||
this.status = this.getResponseProperty("Status");
|
||||
this.type = this.getResponseProperty("Type");
|
||||
this.enabled = this.getResponseProperty("Enabled");
|
||||
this.ssoBound = this.getResponseProperty("SsoBound");
|
||||
this.identifier = this.getResponseProperty("Identifier");
|
||||
this.permissions = new PermissionsApi(this.getResponseProperty("permissions"));
|
||||
this.resetPasswordEnrolled = this.getResponseProperty("ResetPasswordEnrolled");
|
||||
this.userId = this.getResponseProperty("UserId");
|
||||
this.providerId = this.getResponseProperty("ProviderId");
|
||||
this.providerName = this.getResponseProperty("ProviderName");
|
||||
this.familySponsorshipFriendlyName = this.getResponseProperty("FamilySponsorshipFriendlyName");
|
||||
this.familySponsorshipAvailable = this.getResponseProperty("FamilySponsorshipAvailable");
|
||||
this.planProductType = this.getResponseProperty("PlanProductType");
|
||||
this.keyConnectorEnabled = this.getResponseProperty("KeyConnectorEnabled") ?? false;
|
||||
this.keyConnectorUrl = this.getResponseProperty("KeyConnectorUrl");
|
||||
}
|
||||
}
|
||||
@@ -1,8 +0,0 @@
|
||||
import { ProfileOrganizationResponse } from "./profileOrganizationResponse";
|
||||
|
||||
export class ProfileProviderOrganizationResponse extends ProfileOrganizationResponse {
|
||||
constructor(response: any) {
|
||||
super(response);
|
||||
this.keyConnectorEnabled = false;
|
||||
}
|
||||
}
|
||||
@@ -1,30 +0,0 @@
|
||||
import { ProviderUserStatusType } from "../../enums/providerUserStatusType";
|
||||
import { ProviderUserType } from "../../enums/providerUserType";
|
||||
import { PermissionsApi } from "../api/permissionsApi";
|
||||
|
||||
import { BaseResponse } from "./baseResponse";
|
||||
|
||||
export class ProfileProviderResponse extends BaseResponse {
|
||||
id: string;
|
||||
name: string;
|
||||
key: string;
|
||||
status: ProviderUserStatusType;
|
||||
type: ProviderUserType;
|
||||
enabled: boolean;
|
||||
permissions: PermissionsApi;
|
||||
userId: string;
|
||||
useEvents: boolean;
|
||||
|
||||
constructor(response: any) {
|
||||
super(response);
|
||||
this.id = this.getResponseProperty("Id");
|
||||
this.name = this.getResponseProperty("Name");
|
||||
this.key = this.getResponseProperty("Key");
|
||||
this.status = this.getResponseProperty("Status");
|
||||
this.type = this.getResponseProperty("Type");
|
||||
this.enabled = this.getResponseProperty("Enabled");
|
||||
this.permissions = new PermissionsApi(this.getResponseProperty("permissions"));
|
||||
this.userId = this.getResponseProperty("UserId");
|
||||
this.useEvents = this.getResponseProperty("UseEvents");
|
||||
}
|
||||
}
|
||||
@@ -1,55 +0,0 @@
|
||||
import { BaseResponse } from "./baseResponse";
|
||||
import { ProfileOrganizationResponse } from "./profileOrganizationResponse";
|
||||
import { ProfileProviderOrganizationResponse } from "./profileProviderOrganizationResponse";
|
||||
import { ProfileProviderResponse } from "./profileProviderResponse";
|
||||
|
||||
export class ProfileResponse extends BaseResponse {
|
||||
id: string;
|
||||
name: string;
|
||||
email: string;
|
||||
emailVerified: boolean;
|
||||
masterPasswordHint: string;
|
||||
premium: boolean;
|
||||
culture: string;
|
||||
twoFactorEnabled: boolean;
|
||||
key: string;
|
||||
privateKey: string;
|
||||
securityStamp: string;
|
||||
forcePasswordReset: boolean;
|
||||
usesKeyConnector: boolean;
|
||||
organizations: ProfileOrganizationResponse[] = [];
|
||||
providers: ProfileProviderResponse[] = [];
|
||||
providerOrganizations: ProfileProviderOrganizationResponse[] = [];
|
||||
|
||||
constructor(response: any) {
|
||||
super(response);
|
||||
this.id = this.getResponseProperty("Id");
|
||||
this.name = this.getResponseProperty("Name");
|
||||
this.email = this.getResponseProperty("Email");
|
||||
this.emailVerified = this.getResponseProperty("EmailVerified");
|
||||
this.masterPasswordHint = this.getResponseProperty("MasterPasswordHint");
|
||||
this.premium = this.getResponseProperty("Premium");
|
||||
this.culture = this.getResponseProperty("Culture");
|
||||
this.twoFactorEnabled = this.getResponseProperty("TwoFactorEnabled");
|
||||
this.key = this.getResponseProperty("Key");
|
||||
this.privateKey = this.getResponseProperty("PrivateKey");
|
||||
this.securityStamp = this.getResponseProperty("SecurityStamp");
|
||||
this.forcePasswordReset = this.getResponseProperty("ForcePasswordReset") ?? false;
|
||||
this.usesKeyConnector = this.getResponseProperty("UsesKeyConnector") ?? false;
|
||||
|
||||
const organizations = this.getResponseProperty("Organizations");
|
||||
if (organizations != null) {
|
||||
this.organizations = organizations.map((o: any) => new ProfileOrganizationResponse(o));
|
||||
}
|
||||
const providers = this.getResponseProperty("Providers");
|
||||
if (providers != null) {
|
||||
this.providers = providers.map((o: any) => new ProfileProviderResponse(o));
|
||||
}
|
||||
const providerOrganizations = this.getResponseProperty("ProviderOrganizations");
|
||||
if (providerOrganizations != null) {
|
||||
this.providerOrganizations = providerOrganizations.map(
|
||||
(o: any) => new ProfileProviderOrganizationResponse(o),
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,31 +0,0 @@
|
||||
import { BaseResponse } from "../baseResponse";
|
||||
|
||||
export class ProviderOrganizationResponse extends BaseResponse {
|
||||
id: string;
|
||||
providerId: string;
|
||||
organizationId: string;
|
||||
key: string;
|
||||
settings: string;
|
||||
creationDate: string;
|
||||
revisionDate: string;
|
||||
|
||||
constructor(response: any) {
|
||||
super(response);
|
||||
this.id = this.getResponseProperty("Id");
|
||||
this.providerId = this.getResponseProperty("ProviderId");
|
||||
this.organizationId = this.getResponseProperty("OrganizationId");
|
||||
this.key = this.getResponseProperty("Key");
|
||||
this.settings = this.getResponseProperty("Settings");
|
||||
this.creationDate = this.getResponseProperty("CreationDate");
|
||||
this.revisionDate = this.getResponseProperty("RevisionDate");
|
||||
}
|
||||
}
|
||||
|
||||
export class ProviderOrganizationOrganizationDetailsResponse extends ProviderOrganizationResponse {
|
||||
organizationName: string;
|
||||
|
||||
constructor(response: any) {
|
||||
super(response);
|
||||
this.organizationName = this.getResponseProperty("OrganizationName");
|
||||
}
|
||||
}
|
||||
@@ -1,16 +0,0 @@
|
||||
import { BaseResponse } from "../baseResponse";
|
||||
|
||||
export class ProviderResponse extends BaseResponse {
|
||||
id: string;
|
||||
name: string;
|
||||
businessName: string;
|
||||
billingEmail: string;
|
||||
|
||||
constructor(response: any) {
|
||||
super(response);
|
||||
this.id = this.getResponseProperty("Id");
|
||||
this.name = this.getResponseProperty("Name");
|
||||
this.businessName = this.getResponseProperty("BusinessName");
|
||||
this.billingEmail = this.getResponseProperty("BillingEmail");
|
||||
}
|
||||
}
|
||||
@@ -1,3 +0,0 @@
|
||||
import { OrganizationUserBulkPublicKeyResponse } from "../organizationUserBulkPublicKeyResponse";
|
||||
|
||||
export class ProviderUserBulkPublicKeyResponse extends OrganizationUserBulkPublicKeyResponse {}
|
||||
@@ -1,12 +0,0 @@
|
||||
import { BaseResponse } from "../baseResponse";
|
||||
|
||||
export class ProviderUserBulkResponse extends BaseResponse {
|
||||
id: string;
|
||||
error: string;
|
||||
|
||||
constructor(response: any) {
|
||||
super(response);
|
||||
this.id = this.getResponseProperty("Id");
|
||||
this.error = this.getResponseProperty("Error");
|
||||
}
|
||||
}
|
||||
@@ -1,32 +0,0 @@
|
||||
import { ProviderUserStatusType } from "../../../enums/providerUserStatusType";
|
||||
import { ProviderUserType } from "../../../enums/providerUserType";
|
||||
import { PermissionsApi } from "../../api/permissionsApi";
|
||||
import { BaseResponse } from "../baseResponse";
|
||||
|
||||
export class ProviderUserResponse extends BaseResponse {
|
||||
id: string;
|
||||
userId: string;
|
||||
type: ProviderUserType;
|
||||
status: ProviderUserStatusType;
|
||||
permissions: PermissionsApi;
|
||||
|
||||
constructor(response: any) {
|
||||
super(response);
|
||||
this.id = this.getResponseProperty("Id");
|
||||
this.userId = this.getResponseProperty("UserId");
|
||||
this.type = this.getResponseProperty("Type");
|
||||
this.status = this.getResponseProperty("Status");
|
||||
this.permissions = new PermissionsApi(this.getResponseProperty("Permissions"));
|
||||
}
|
||||
}
|
||||
|
||||
export class ProviderUserUserDetailsResponse extends ProviderUserResponse {
|
||||
name: string;
|
||||
email: string;
|
||||
|
||||
constructor(response: any) {
|
||||
super(response);
|
||||
this.name = this.getResponseProperty("Name");
|
||||
this.email = this.getResponseProperty("Email");
|
||||
}
|
||||
}
|
||||
@@ -1,14 +0,0 @@
|
||||
import { BaseResponse } from "./baseResponse";
|
||||
|
||||
export class SelectionReadOnlyResponse extends BaseResponse {
|
||||
id: string;
|
||||
readOnly: boolean;
|
||||
hidePasswords: boolean;
|
||||
|
||||
constructor(response: any) {
|
||||
super(response);
|
||||
this.id = this.getResponseProperty("Id");
|
||||
this.readOnly = this.getResponseProperty("ReadOnly");
|
||||
this.hidePasswords = this.getResponseProperty("HidePasswords");
|
||||
}
|
||||
}
|
||||
@@ -1,85 +0,0 @@
|
||||
import { BaseResponse } from "./baseResponse";
|
||||
|
||||
export class SubscriptionResponse extends BaseResponse {
|
||||
storageName: string;
|
||||
storageGb: number;
|
||||
maxStorageGb: number;
|
||||
subscription: BillingSubscriptionResponse;
|
||||
upcomingInvoice: BillingSubscriptionUpcomingInvoiceResponse;
|
||||
license: any;
|
||||
expiration: string;
|
||||
usingInAppPurchase: boolean;
|
||||
|
||||
constructor(response: any) {
|
||||
super(response);
|
||||
this.storageName = this.getResponseProperty("StorageName");
|
||||
this.storageGb = this.getResponseProperty("StorageGb");
|
||||
this.maxStorageGb = this.getResponseProperty("MaxStorageGb");
|
||||
this.license = this.getResponseProperty("License");
|
||||
this.expiration = this.getResponseProperty("Expiration");
|
||||
this.usingInAppPurchase = this.getResponseProperty("UsingInAppPurchase");
|
||||
const subscription = this.getResponseProperty("Subscription");
|
||||
const upcomingInvoice = this.getResponseProperty("UpcomingInvoice");
|
||||
this.subscription = subscription == null ? null : new BillingSubscriptionResponse(subscription);
|
||||
this.upcomingInvoice =
|
||||
upcomingInvoice == null
|
||||
? null
|
||||
: new BillingSubscriptionUpcomingInvoiceResponse(upcomingInvoice);
|
||||
}
|
||||
}
|
||||
|
||||
export class BillingSubscriptionResponse extends BaseResponse {
|
||||
trialStartDate: string;
|
||||
trialEndDate: string;
|
||||
periodStartDate: string;
|
||||
periodEndDate: string;
|
||||
cancelledDate: string;
|
||||
cancelAtEndDate: boolean;
|
||||
status: string;
|
||||
cancelled: boolean;
|
||||
items: BillingSubscriptionItemResponse[] = [];
|
||||
|
||||
constructor(response: any) {
|
||||
super(response);
|
||||
this.trialEndDate = this.getResponseProperty("TrialStartDate");
|
||||
this.trialEndDate = this.getResponseProperty("TrialEndDate");
|
||||
this.periodStartDate = this.getResponseProperty("PeriodStartDate");
|
||||
this.periodEndDate = this.getResponseProperty("PeriodEndDate");
|
||||
this.cancelledDate = this.getResponseProperty("CancelledDate");
|
||||
this.cancelAtEndDate = this.getResponseProperty("CancelAtEndDate");
|
||||
this.status = this.getResponseProperty("Status");
|
||||
this.cancelled = this.getResponseProperty("Cancelled");
|
||||
const items = this.getResponseProperty("Items");
|
||||
if (items != null) {
|
||||
this.items = items.map((i: any) => new BillingSubscriptionItemResponse(i));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
export class BillingSubscriptionItemResponse extends BaseResponse {
|
||||
name: string;
|
||||
amount: number;
|
||||
quantity: number;
|
||||
interval: string;
|
||||
sponsoredSubscriptionItem: boolean;
|
||||
|
||||
constructor(response: any) {
|
||||
super(response);
|
||||
this.name = this.getResponseProperty("Name");
|
||||
this.amount = this.getResponseProperty("Amount");
|
||||
this.quantity = this.getResponseProperty("Quantity");
|
||||
this.interval = this.getResponseProperty("Interval");
|
||||
this.sponsoredSubscriptionItem = this.getResponseProperty("SponsoredSubscriptionItem");
|
||||
}
|
||||
}
|
||||
|
||||
export class BillingSubscriptionUpcomingInvoiceResponse extends BaseResponse {
|
||||
date: string;
|
||||
amount: number;
|
||||
|
||||
constructor(response: any) {
|
||||
super(response);
|
||||
this.date = this.getResponseProperty("Date");
|
||||
this.amount = this.getResponseProperty("Amount");
|
||||
}
|
||||
}
|
||||
@@ -1,24 +0,0 @@
|
||||
import { BaseResponse } from "./baseResponse";
|
||||
|
||||
export class TaxInfoResponse extends BaseResponse {
|
||||
taxId: string;
|
||||
taxIdType: string;
|
||||
line1: string;
|
||||
line2: string;
|
||||
city: string;
|
||||
state: string;
|
||||
country: string;
|
||||
postalCode: string;
|
||||
|
||||
constructor(response: any) {
|
||||
super(response);
|
||||
this.taxId = this.getResponseProperty("TaxIdNumber");
|
||||
this.taxIdType = this.getResponseProperty("TaxIdType");
|
||||
this.line1 = this.getResponseProperty("Line1");
|
||||
this.line2 = this.getResponseProperty("Line2");
|
||||
this.city = this.getResponseProperty("City");
|
||||
this.state = this.getResponseProperty("State");
|
||||
this.postalCode = this.getResponseProperty("PostalCode");
|
||||
this.country = this.getResponseProperty("Country");
|
||||
}
|
||||
}
|
||||
@@ -1,18 +0,0 @@
|
||||
import { BaseResponse } from "./baseResponse";
|
||||
|
||||
export class TaxRateResponse extends BaseResponse {
|
||||
id: string;
|
||||
country: string;
|
||||
state: string;
|
||||
postalCode: string;
|
||||
rate: number;
|
||||
|
||||
constructor(response: any) {
|
||||
super(response);
|
||||
this.id = this.getResponseProperty("Id");
|
||||
this.country = this.getResponseProperty("Country");
|
||||
this.state = this.getResponseProperty("State");
|
||||
this.postalCode = this.getResponseProperty("PostalCode");
|
||||
this.rate = this.getResponseProperty("Rate");
|
||||
}
|
||||
}
|
||||
@@ -1,12 +0,0 @@
|
||||
import { BaseResponse } from "./baseResponse";
|
||||
|
||||
export class TwoFactorAuthenticatorResponse extends BaseResponse {
|
||||
enabled: boolean;
|
||||
key: string;
|
||||
|
||||
constructor(response: any) {
|
||||
super(response);
|
||||
this.enabled = this.getResponseProperty("Enabled");
|
||||
this.key = this.getResponseProperty("Key");
|
||||
}
|
||||
}
|
||||
@@ -1,16 +0,0 @@
|
||||
import { BaseResponse } from "./baseResponse";
|
||||
|
||||
export class TwoFactorDuoResponse extends BaseResponse {
|
||||
enabled: boolean;
|
||||
host: string;
|
||||
secretKey: string;
|
||||
integrationKey: string;
|
||||
|
||||
constructor(response: any) {
|
||||
super(response);
|
||||
this.enabled = this.getResponseProperty("Enabled");
|
||||
this.host = this.getResponseProperty("Host");
|
||||
this.secretKey = this.getResponseProperty("SecretKey");
|
||||
this.integrationKey = this.getResponseProperty("IntegrationKey");
|
||||
}
|
||||
}
|
||||
@@ -1,12 +0,0 @@
|
||||
import { BaseResponse } from "./baseResponse";
|
||||
|
||||
export class TwoFactorEmailResponse extends BaseResponse {
|
||||
enabled: boolean;
|
||||
email: string;
|
||||
|
||||
constructor(response: any) {
|
||||
super(response);
|
||||
this.enabled = this.getResponseProperty("Enabled");
|
||||
this.email = this.getResponseProperty("Email");
|
||||
}
|
||||
}
|
||||
@@ -1,14 +0,0 @@
|
||||
import { TwoFactorProviderType } from "../../enums/twoFactorProviderType";
|
||||
|
||||
import { BaseResponse } from "./baseResponse";
|
||||
|
||||
export class TwoFactorProviderResponse extends BaseResponse {
|
||||
enabled: boolean;
|
||||
type: TwoFactorProviderType;
|
||||
|
||||
constructor(response: any) {
|
||||
super(response);
|
||||
this.enabled = this.getResponseProperty("Enabled");
|
||||
this.type = this.getResponseProperty("Type");
|
||||
}
|
||||
}
|
||||
@@ -1,10 +0,0 @@
|
||||
import { BaseResponse } from "./baseResponse";
|
||||
|
||||
export class TwoFactorRecoverResponse extends BaseResponse {
|
||||
code: string;
|
||||
|
||||
constructor(response: any) {
|
||||
super(response);
|
||||
this.code = this.getResponseProperty("Code");
|
||||
}
|
||||
}
|
||||
@@ -1,60 +0,0 @@
|
||||
import { Utils } from "../../misc/utils";
|
||||
|
||||
import { BaseResponse } from "./baseResponse";
|
||||
|
||||
export class TwoFactorWebAuthnResponse extends BaseResponse {
|
||||
enabled: boolean;
|
||||
keys: KeyResponse[];
|
||||
|
||||
constructor(response: any) {
|
||||
super(response);
|
||||
this.enabled = this.getResponseProperty("Enabled");
|
||||
const keys = this.getResponseProperty("Keys");
|
||||
this.keys = keys == null ? null : keys.map((k: any) => new KeyResponse(k));
|
||||
}
|
||||
}
|
||||
|
||||
export class KeyResponse extends BaseResponse {
|
||||
name: string;
|
||||
id: number;
|
||||
migrated: boolean;
|
||||
|
||||
constructor(response: any) {
|
||||
super(response);
|
||||
this.name = this.getResponseProperty("Name");
|
||||
this.id = this.getResponseProperty("Id");
|
||||
this.migrated = this.getResponseProperty("Migrated");
|
||||
}
|
||||
}
|
||||
|
||||
export class ChallengeResponse extends BaseResponse implements PublicKeyCredentialCreationOptions {
|
||||
attestation?: AttestationConveyancePreference;
|
||||
authenticatorSelection?: AuthenticatorSelectionCriteria;
|
||||
challenge: BufferSource;
|
||||
excludeCredentials?: PublicKeyCredentialDescriptor[];
|
||||
extensions?: AuthenticationExtensionsClientInputs;
|
||||
pubKeyCredParams: PublicKeyCredentialParameters[];
|
||||
rp: PublicKeyCredentialRpEntity;
|
||||
timeout?: number;
|
||||
user: PublicKeyCredentialUserEntity;
|
||||
|
||||
constructor(response: any) {
|
||||
super(response);
|
||||
this.attestation = this.getResponseProperty("attestation");
|
||||
this.authenticatorSelection = this.getResponseProperty("authenticatorSelection");
|
||||
this.challenge = Utils.fromUrlB64ToArray(this.getResponseProperty("challenge"));
|
||||
this.excludeCredentials = this.getResponseProperty("excludeCredentials").map((c: any) => {
|
||||
c.id = Utils.fromUrlB64ToArray(c.id).buffer;
|
||||
return c;
|
||||
});
|
||||
this.extensions = this.getResponseProperty("extensions");
|
||||
this.pubKeyCredParams = this.getResponseProperty("pubKeyCredParams");
|
||||
this.rp = this.getResponseProperty("rp");
|
||||
this.timeout = this.getResponseProperty("timeout");
|
||||
|
||||
const user = this.getResponseProperty("user");
|
||||
user.id = Utils.fromUrlB64ToArray(user.id);
|
||||
|
||||
this.user = user;
|
||||
}
|
||||
}
|
||||
@@ -1,22 +0,0 @@
|
||||
import { BaseResponse } from "./baseResponse";
|
||||
|
||||
export class TwoFactorYubiKeyResponse extends BaseResponse {
|
||||
enabled: boolean;
|
||||
key1: string;
|
||||
key2: string;
|
||||
key3: string;
|
||||
key4: string;
|
||||
key5: string;
|
||||
nfc: boolean;
|
||||
|
||||
constructor(response: any) {
|
||||
super(response);
|
||||
this.enabled = this.getResponseProperty("Enabled");
|
||||
this.key1 = this.getResponseProperty("Key1");
|
||||
this.key2 = this.getResponseProperty("Key2");
|
||||
this.key3 = this.getResponseProperty("Key3");
|
||||
this.key4 = this.getResponseProperty("Key4");
|
||||
this.key5 = this.getResponseProperty("Key5");
|
||||
this.nfc = this.getResponseProperty("Nfc");
|
||||
}
|
||||
}
|
||||
@@ -1,12 +0,0 @@
|
||||
import { BaseResponse } from "./baseResponse";
|
||||
|
||||
export class UserKeyResponse extends BaseResponse {
|
||||
userId: string;
|
||||
publicKey: string;
|
||||
|
||||
constructor(response: any) {
|
||||
super(response);
|
||||
this.userId = this.getResponseProperty("UserId");
|
||||
this.publicKey = this.getResponseProperty("PublicKey");
|
||||
}
|
||||
}
|
||||
@@ -1,104 +0,0 @@
|
||||
import {
|
||||
OpenIdConnectRedirectBehavior,
|
||||
Saml2BindingType,
|
||||
Saml2NameIdFormat,
|
||||
Saml2SigningBehavior,
|
||||
SsoType,
|
||||
} from "../../enums/ssoEnums";
|
||||
import { SsoConfigApi } from "../api/ssoConfigApi";
|
||||
|
||||
import { View } from "./view";
|
||||
|
||||
export class SsoConfigView extends View {
|
||||
configType: SsoType;
|
||||
|
||||
keyConnectorEnabled: boolean;
|
||||
keyConnectorUrl: string;
|
||||
|
||||
openId: {
|
||||
authority: string;
|
||||
clientId: string;
|
||||
clientSecret: string;
|
||||
metadataAddress: string;
|
||||
redirectBehavior: OpenIdConnectRedirectBehavior;
|
||||
getClaimsFromUserInfoEndpoint: boolean;
|
||||
additionalScopes: string;
|
||||
additionalUserIdClaimTypes: string;
|
||||
additionalEmailClaimTypes: string;
|
||||
additionalNameClaimTypes: string;
|
||||
acrValues: string;
|
||||
expectedReturnAcrValue: string;
|
||||
};
|
||||
|
||||
saml: {
|
||||
spNameIdFormat: Saml2NameIdFormat;
|
||||
spOutboundSigningAlgorithm: string;
|
||||
spSigningBehavior: Saml2SigningBehavior;
|
||||
spMinIncomingSigningAlgorithm: boolean;
|
||||
spWantAssertionsSigned: boolean;
|
||||
spValidateCertificates: boolean;
|
||||
|
||||
idpEntityId: string;
|
||||
idpBindingType: Saml2BindingType;
|
||||
idpSingleSignOnServiceUrl: string;
|
||||
idpSingleLogoutServiceUrl: string;
|
||||
idpX509PublicCert: string;
|
||||
idpOutboundSigningAlgorithm: string;
|
||||
idpAllowUnsolicitedAuthnResponse: boolean;
|
||||
idpAllowOutboundLogoutRequests: boolean;
|
||||
idpWantAuthnRequestsSigned: boolean;
|
||||
};
|
||||
|
||||
constructor(api: SsoConfigApi) {
|
||||
super();
|
||||
if (api == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
this.configType = api.configType;
|
||||
|
||||
this.keyConnectorEnabled = api.keyConnectorEnabled;
|
||||
this.keyConnectorUrl = api.keyConnectorUrl;
|
||||
|
||||
if (this.configType === SsoType.OpenIdConnect) {
|
||||
this.openId = {
|
||||
authority: api.authority,
|
||||
clientId: api.clientId,
|
||||
clientSecret: api.clientSecret,
|
||||
metadataAddress: api.metadataAddress,
|
||||
redirectBehavior: api.redirectBehavior,
|
||||
getClaimsFromUserInfoEndpoint: api.getClaimsFromUserInfoEndpoint,
|
||||
additionalScopes: api.additionalScopes,
|
||||
additionalUserIdClaimTypes: api.additionalUserIdClaimTypes,
|
||||
additionalEmailClaimTypes: api.additionalEmailClaimTypes,
|
||||
additionalNameClaimTypes: api.additionalNameClaimTypes,
|
||||
acrValues: api.acrValues,
|
||||
expectedReturnAcrValue: api.expectedReturnAcrValue,
|
||||
};
|
||||
} else if (this.configType === SsoType.Saml2) {
|
||||
this.saml = {
|
||||
spNameIdFormat: api.spNameIdFormat,
|
||||
spOutboundSigningAlgorithm: api.spOutboundSigningAlgorithm,
|
||||
spSigningBehavior: api.spSigningBehavior,
|
||||
spMinIncomingSigningAlgorithm: api.spMinIncomingSigningAlgorithm,
|
||||
spWantAssertionsSigned: api.spWantAssertionsSigned,
|
||||
spValidateCertificates: api.spValidateCertificates,
|
||||
|
||||
idpEntityId: api.idpEntityId,
|
||||
idpBindingType: api.idpBindingType,
|
||||
idpSingleSignOnServiceUrl: api.idpSingleSignOnServiceUrl,
|
||||
idpSingleLogoutServiceUrl: api.idpSingleLogoutServiceUrl,
|
||||
idpX509PublicCert: api.idpX509PublicCert,
|
||||
idpOutboundSigningAlgorithm: api.idpOutboundSigningAlgorithm,
|
||||
idpAllowUnsolicitedAuthnResponse: api.idpAllowUnsolicitedAuthnResponse,
|
||||
idpWantAuthnRequestsSigned: api.idpWantAuthnRequestsSigned,
|
||||
|
||||
// Value is inverted in the view model (allow instead of disable)
|
||||
idpAllowOutboundLogoutRequests:
|
||||
api.idpDisableOutboundLogoutRequests == null
|
||||
? null
|
||||
: !api.idpDisableOutboundLogoutRequests,
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1 +0,0 @@
|
||||
export class View {}
|
||||
@@ -1,9 +0,0 @@
|
||||
import { ElectronLogService } from "@/jslib/electron/src/services/electronLog.service";
|
||||
|
||||
describe("ElectronLogService", () => {
|
||||
it("sets dev based on electron method", () => {
|
||||
process.env.ELECTRON_IS_DEV = "1";
|
||||
const logService = new ElectronLogService();
|
||||
expect(logService).toEqual(expect.objectContaining({ isDev: true }) as any);
|
||||
});
|
||||
});
|
||||
@@ -1,27 +0,0 @@
|
||||
import { cleanUserAgent } from "@/jslib/electron/src/utils";
|
||||
|
||||
const expectedUserAgent = `Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/${process.versions.chrome} Safari/537.36`;
|
||||
|
||||
describe("cleanUserAgent", () => {
|
||||
it("cleans mac agent", () => {
|
||||
const initialMacAgent = `Mozilla/5.0 (Macintosh; Intel Mac OS X 11_6_0) AppleWebKit/537.36 (KHTML, like Gecko) Bitwarden/${process.version} Chrome/${process.versions.chrome} Electron/${process.versions.electron} Safari/537.36`;
|
||||
expect(cleanUserAgent(initialMacAgent)).toEqual(expectedUserAgent);
|
||||
});
|
||||
|
||||
it("cleans windows agent", () => {
|
||||
const initialWindowsAgent = `Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Bitwarden/${process.version} Chrome/${process.versions.chrome} Electron/${process.versions.electron} Safari/537.36`;
|
||||
expect(cleanUserAgent(initialWindowsAgent)).toEqual(expectedUserAgent);
|
||||
});
|
||||
|
||||
it("cleans linux agent", () => {
|
||||
const initialWindowsAgent = `Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Bitwarden/${process.version} Chrome/${process.versions.chrome} Electron/${process.versions.electron} Safari/537.36`;
|
||||
expect(cleanUserAgent(initialWindowsAgent)).toEqual(expectedUserAgent);
|
||||
});
|
||||
|
||||
it("does not change version numbers", () => {
|
||||
const expected = `Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/87.0.4280.141 Safari/537.36`;
|
||||
const initialAgent = `Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Bitwarden/1.28.3 Chrome/87.0.4280.141 Electron/11.4.5 Safari/537.36`;
|
||||
|
||||
expect(cleanUserAgent(initialAgent)).toEqual(expected);
|
||||
});
|
||||
});
|
||||
@@ -1,44 +0,0 @@
|
||||
import {
|
||||
interceptConsole,
|
||||
restoreConsole,
|
||||
} from "@/jslib/common/spec/services/consoleLog.service.spec";
|
||||
import { ConsoleLogService } from "@/jslib/node/src/cli/services/consoleLog.service";
|
||||
|
||||
let caughtMessage: any = {};
|
||||
|
||||
describe("CLI Console log service", () => {
|
||||
let logService: ConsoleLogService;
|
||||
beforeEach(() => {
|
||||
caughtMessage = {};
|
||||
interceptConsole(caughtMessage);
|
||||
logService = new ConsoleLogService(true);
|
||||
});
|
||||
|
||||
afterAll(() => {
|
||||
restoreConsole();
|
||||
});
|
||||
|
||||
it("should redirect all console to error if BW_RESPONSE env is true", () => {
|
||||
process.env.BW_RESPONSE = "true";
|
||||
|
||||
logService.debug("this is a debug message");
|
||||
expect(caughtMessage).toMatchObject({
|
||||
error: { 0: "this is a debug message" },
|
||||
});
|
||||
});
|
||||
|
||||
it("should not redirect console to error if BW_RESPONSE != true", () => {
|
||||
process.env.BW_RESPONSE = "false";
|
||||
|
||||
logService.debug("debug");
|
||||
logService.info("info");
|
||||
logService.warning("warning");
|
||||
logService.error("error");
|
||||
|
||||
expect(caughtMessage).toMatchObject({
|
||||
log: { 0: "info" },
|
||||
warn: { 0: "warning" },
|
||||
error: { 0: "error" },
|
||||
});
|
||||
});
|
||||
});
|
||||
@@ -1,518 +0,0 @@
|
||||
import { Utils } from "@/jslib/common/src/misc/utils";
|
||||
import { SymmetricCryptoKey } from "@/jslib/common/src/models/domain/symmetricCryptoKey";
|
||||
import { NodeCryptoFunctionService } from "@/jslib/node/src/services/nodeCryptoFunction.service";
|
||||
|
||||
const RsaPublicKey =
|
||||
"MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAl0Vawl/toXzkEvB82FEtqHP" +
|
||||
"4xlU2ab/v0crqIfXfIoWF/XXdHGIdrZeilnRXPPJT1B9dTsasttEZNnua/0Rek/cjNDHtzT52irfoZYS7X6HNIfOi54Q+egP" +
|
||||
"RQ1H7iNHVZz3K8Db9GCSKPeC8MbW6gVCzb15esCe1gGzg6wkMuWYDFYPoh/oBqcIqrGah7firqB1nDedzEjw32heP2DAffVN" +
|
||||
"084iTDjiWrJNUxBJ2pDD5Z9dT3MzQ2s09ew1yMWK2z37rT3YerC7OgEDmo3WYo3xL3qYJznu3EO2nmrYjiRa40wKSjxsTlUc" +
|
||||
"xDF+F0uMW8oR9EMUHgepdepfAtLsSAQIDAQAB";
|
||||
const RsaPrivateKey =
|
||||
"MIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQCXRVrCX+2hfOQS8Hz" +
|
||||
"YUS2oc/jGVTZpv+/Ryuoh9d8ihYX9dd0cYh2tl6KWdFc88lPUH11Oxqy20Rk2e5r/RF6T9yM0Me3NPnaKt+hlhLtfoc0h86L" +
|
||||
"nhD56A9FDUfuI0dVnPcrwNv0YJIo94LwxtbqBULNvXl6wJ7WAbODrCQy5ZgMVg+iH+gGpwiqsZqHt+KuoHWcN53MSPDfaF4/" +
|
||||
"YMB99U3TziJMOOJask1TEEnakMPln11PczNDazT17DXIxYrbPfutPdh6sLs6AQOajdZijfEvepgnOe7cQ7aeatiOJFrjTApK" +
|
||||
"PGxOVRzEMX4XS4xbyhH0QxQeB6l16l8C0uxIBAgMBAAECggEASaWfeVDA3cVzOPFSpvJm20OTE+R6uGOU+7vh36TX/POq92q" +
|
||||
"Buwbd0h0oMD32FxsXywd2IxtBDUSiFM9699qufTVuM0Q3tZw6lHDTOVG08+tPdr8qSbMtw7PGFxN79fHLBxejjO4IrM9lapj" +
|
||||
"WpxEF+11x7r+wM+0xRZQ8sNFYG46aPfIaty4BGbL0I2DQ2y8I57iBCAy69eht59NLMm27fRWGJIWCuBIjlpfzET1j2HLXUIh" +
|
||||
"5bTBNzqaN039WH49HczGE3mQKVEJZc/efk3HaVd0a1Sjzyn0QY+N1jtZN3jTRbuDWA1AknkX1LX/0tUhuS3/7C3ejHxjw4Dk" +
|
||||
"1ZLo5/QKBgQDIWvqFn0+IKRSu6Ua2hDsufIHHUNLelbfLUMmFthxabcUn4zlvIscJO00Tq/ezopSRRvbGiqnxjv/mYxucvOU" +
|
||||
"BeZtlus0Q9RTACBtw9TGoNTmQbEunJ2FOSlqbQxkBBAjgGEppRPt30iGj/VjAhCATq2MYOa/X4dVR51BqQAFIEwKBgQDBSIf" +
|
||||
"TFKC/hDk6FKZlgwvupWYJyU9RkyfstPErZFmzoKhPkQ3YORo2oeAYmVUbS9I2iIYpYpYQJHX8jMuCbCz4ONxTCuSIXYQYUcU" +
|
||||
"q4PglCKp31xBAE6TN8SvhfME9/MvuDssnQinAHuF0GDAhF646T3LLS1not6Vszv7brwSoGwKBgQC88v/8cGfi80ssQZeMnVv" +
|
||||
"q1UTXIeQcQnoY5lGHJl3K8mbS3TnXE6c9j417Fdz+rj8KWzBzwWXQB5pSPflWcdZO886Xu/mVGmy9RWgLuVFhXwCwsVEPjNX" +
|
||||
"5ramRb0/vY0yzenUCninBsIxFSbIfrPtLUYCc4hpxr+sr2Mg/y6jpvQKBgBezMRRs3xkcuXepuI2R+BCXL1/b02IJTUf1F+1" +
|
||||
"eLLGd7YV0H+J3fgNc7gGWK51hOrF9JBZHBGeOUPlaukmPwiPdtQZpu4QNE3l37VlIpKTF30E6mb+BqR+nht3rUjarnMXgAoE" +
|
||||
"Z18y6/KIjpSMpqC92Nnk/EBM9EYe6Cf4eA9ApAoGAeqEUg46UTlJySkBKURGpIs3v1kkf5I0X8DnOhwb+HPxNaiEdmO7ckm8" +
|
||||
"+tPVgppLcG0+tMdLjigFQiDUQk2y3WjyxP5ZvXu7U96jaJRI8PFMoE06WeVYcdIzrID2HvqH+w0UQJFrLJ/0Mn4stFAEzXKZ" +
|
||||
"BokBGnjFnTnKcs7nv/O8=";
|
||||
|
||||
const Sha1Mac = "4d4c223f95dc577b665ec4ccbcb680b80a397038";
|
||||
const Sha256Mac = "6be3caa84922e12aaaaa2f16c40d44433bb081ef323db584eb616333ab4e874f";
|
||||
const Sha512Mac =
|
||||
"21910e341fa12106ca35758a2285374509326c9fbe0bd64e7b99c898f841dc948c58ce66d3504d8883c" +
|
||||
"5ea7817a0b7c5d4d9b00364ccd214669131fc17fe4aca";
|
||||
|
||||
describe("NodeCrypto Function Service", () => {
|
||||
describe("pbkdf2", () => {
|
||||
const regular256Key = "pj9prw/OHPleXI6bRdmlaD+saJS4awrMiQsQiDjeu2I=";
|
||||
const utf8256Key = "yqvoFXgMRmHR3QPYr5pyR4uVuoHkltv9aHUP63p8n7I=";
|
||||
const unicode256Key = "ZdeOata6xoRpB4DLp8zHhXz5kLmkWtX5pd+TdRH8w8w=";
|
||||
|
||||
const regular512Key =
|
||||
"liTi/Ke8LPU1Qv+Vl7NGEVt/XMbsBVJ2kQxtVG/Z1/JFHFKQW3ZkI81qVlwTiCpb+cFXzs+57" +
|
||||
"eyhhx5wfKo5Cg==";
|
||||
const utf8512Key =
|
||||
"df0KdvIBeCzD/kyXptwQohaqUa4e7IyFUyhFQjXCANu5T+scq55hCcE4dG4T/MhAk2exw8j7ixRN" +
|
||||
"zXANiVZpnw==";
|
||||
const unicode512Key =
|
||||
"FE+AnUJaxv8jh+zUDtZz4mjjcYk0/PZDZm+SLJe3XtxtnpdqqpblX6JjuMZt/dYYNMOrb2+mD" +
|
||||
"L3FiQDTROh1lg==";
|
||||
|
||||
testPbkdf2("sha256", regular256Key, utf8256Key, unicode256Key);
|
||||
testPbkdf2("sha512", regular512Key, utf8512Key, unicode512Key);
|
||||
});
|
||||
|
||||
describe("hkdf", () => {
|
||||
const regular256Key = "qBUmEYtwTwwGPuw/z6bs/qYXXYNUlocFlyAuuANI8Pw=";
|
||||
const utf8256Key = "6DfJwW1R3txgiZKkIFTvVAb7qVlG7lKcmJGJoxR2GBU=";
|
||||
const unicode256Key = "gejGI82xthA+nKtKmIh82kjw+ttHr+ODsUoGdu5sf0A=";
|
||||
|
||||
const regular512Key = "xe5cIG6ZfwGmb1FvsOedM0XKOm21myZkjL/eDeKIqqM=";
|
||||
const utf8512Key = "XQMVBnxVEhlvjSFDQc77j5GDE9aorvbS0vKnjhRg0LY=";
|
||||
const unicode512Key = "148GImrTbrjaGAe/iWEpclINM8Ehhko+9lB14+52lqc=";
|
||||
|
||||
testHkdf("sha256", regular256Key, utf8256Key, unicode256Key);
|
||||
testHkdf("sha512", regular512Key, utf8512Key, unicode512Key);
|
||||
});
|
||||
|
||||
describe("hkdfExpand", () => {
|
||||
const prk16Byte = "criAmKtfzxanbgea5/kelQ==";
|
||||
const prk32Byte = "F5h4KdYQnIVH4rKH0P9CZb1GrR4n16/sJrS0PsQEn0Y=";
|
||||
const prk64Byte =
|
||||
"ssBK0mRG17VHdtsgt8yo4v25CRNpauH+0r2fwY/E9rLyaFBAOMbIeTry+" +
|
||||
"gUJ28p8y+hFh3EI9pcrEWaNvFYonQ==";
|
||||
|
||||
testHkdfExpand("sha256", prk32Byte, 32, "BnIqJlfnHm0e/2iB/15cbHyR19ARPIcWRp4oNS22CD8=");
|
||||
testHkdfExpand(
|
||||
"sha256",
|
||||
prk32Byte,
|
||||
64,
|
||||
"BnIqJlfnHm0e/2iB/15cbHyR19ARPIcWRp4oNS22CD9BV+" +
|
||||
"/queOZenPNkDhmlVyL2WZ3OSU5+7ISNF5NhNfvZA==",
|
||||
);
|
||||
testHkdfExpand("sha512", prk64Byte, 32, "uLWbMWodSBms5uGJ5WTRTesyW+MD7nlpCZvagvIRXlk=");
|
||||
testHkdfExpand(
|
||||
"sha512",
|
||||
prk64Byte,
|
||||
64,
|
||||
"uLWbMWodSBms5uGJ5WTRTesyW+MD7nlpCZvagvIRXlkY5Pv0sB+" +
|
||||
"MqvaopmkC6sD/j89zDwTV9Ib2fpucUydO8w==",
|
||||
);
|
||||
|
||||
it("should fail with prk too small", async () => {
|
||||
const cryptoFunctionService = new NodeCryptoFunctionService();
|
||||
const f = cryptoFunctionService.hkdfExpand(
|
||||
Utils.fromB64ToArray(prk16Byte).buffer,
|
||||
"info",
|
||||
32,
|
||||
"sha256",
|
||||
);
|
||||
await expect(f).rejects.toEqual(new Error("prk is too small."));
|
||||
});
|
||||
|
||||
it("should fail with outputByteSize is too large", async () => {
|
||||
const cryptoFunctionService = new NodeCryptoFunctionService();
|
||||
const f = cryptoFunctionService.hkdfExpand(
|
||||
Utils.fromB64ToArray(prk32Byte).buffer,
|
||||
"info",
|
||||
8161,
|
||||
"sha256",
|
||||
);
|
||||
await expect(f).rejects.toEqual(new Error("outputByteSize is too large."));
|
||||
});
|
||||
});
|
||||
|
||||
describe("hash", () => {
|
||||
const regular1Hash = "2a241604fb921fad12bf877282457268e1dccb70";
|
||||
const utf81Hash = "85672798dc5831e96d6c48655d3d39365a9c88b6";
|
||||
const unicode1Hash = "39c975935054a3efc805a9709b60763a823a6ad4";
|
||||
|
||||
const regular256Hash = "2b8e96031d352a8655d733d7a930b5ffbea69dc25cf65c7bca7dd946278908b2";
|
||||
const utf8256Hash = "25fe8440f5b01ed113b0a0e38e721b126d2f3f77a67518c4a04fcde4e33eeb9d";
|
||||
const unicode256Hash = "adc1c0c2afd6e92cefdf703f9b6eb2c38e0d6d1a040c83f8505c561fea58852e";
|
||||
|
||||
const regular512Hash =
|
||||
"c15cf11d43bde333647e3f559ec4193bb2edeaa0e8b902772f514cdf3f785a3f49a6e02a4b87b3" +
|
||||
"b47523271ad45b7e0aebb5cdcc1bc54815d256eb5dcb80da9d";
|
||||
const utf8512Hash =
|
||||
"035c31a877a291af09ed2d3a1a293e69c3e079ea2cecc00211f35e6bce10474ca3ad6e30b59e26118" +
|
||||
"37463f20969c5bc95282965a051a88f8cdf2e166549fcdd";
|
||||
const unicode512Hash =
|
||||
"2b16a5561af8ad6fe414cc103fc8036492e1fc6d9aabe1b655497054f760fe0e34c5d100ac773d" +
|
||||
"9f3030438284f22dbfa20cb2e9b019f2c98dfe38ce1ef41bae";
|
||||
|
||||
const regularMd5 = "5eceffa53a5fd58c44134211e2c5f522";
|
||||
const utf8Md5 = "3abc9433c09551b939c80aa0aa3174e1";
|
||||
const unicodeMd5 = "85ae134072c8d81257933f7045ba17ca";
|
||||
|
||||
testHash("sha1", regular1Hash, utf81Hash, unicode1Hash);
|
||||
testHash("sha256", regular256Hash, utf8256Hash, unicode256Hash);
|
||||
testHash("sha512", regular512Hash, utf8512Hash, unicode512Hash);
|
||||
testHash("md5", regularMd5, utf8Md5, unicodeMd5);
|
||||
});
|
||||
|
||||
describe("hmac", () => {
|
||||
testHmac("sha1", Sha1Mac);
|
||||
testHmac("sha256", Sha256Mac);
|
||||
testHmac("sha512", Sha512Mac);
|
||||
});
|
||||
|
||||
describe("compare", () => {
|
||||
testCompare(false);
|
||||
});
|
||||
|
||||
describe("hmacFast", () => {
|
||||
testHmac("sha1", Sha1Mac, true);
|
||||
testHmac("sha256", Sha256Mac, true);
|
||||
testHmac("sha512", Sha512Mac, true);
|
||||
});
|
||||
|
||||
describe("compareFast", () => {
|
||||
testCompare(true);
|
||||
});
|
||||
|
||||
describe("aesEncrypt", () => {
|
||||
it("should successfully encrypt data", async () => {
|
||||
const nodeCryptoFunctionService = new NodeCryptoFunctionService();
|
||||
const iv = makeStaticByteArray(16);
|
||||
const key = makeStaticByteArray(32);
|
||||
const data = Utils.fromUtf8ToArray("EncryptMe!");
|
||||
const encValue = await nodeCryptoFunctionService.aesEncrypt(
|
||||
data.buffer,
|
||||
iv.buffer,
|
||||
key.buffer,
|
||||
);
|
||||
expect(Utils.fromBufferToB64(encValue)).toBe("ByUF8vhyX4ddU9gcooznwA==");
|
||||
});
|
||||
|
||||
it("should successfully encrypt and then decrypt data", async () => {
|
||||
const nodeCryptoFunctionService = new NodeCryptoFunctionService();
|
||||
const iv = makeStaticByteArray(16);
|
||||
const key = makeStaticByteArray(32);
|
||||
const value = "EncryptMe!";
|
||||
const data = Utils.fromUtf8ToArray(value);
|
||||
const encValue = await nodeCryptoFunctionService.aesEncrypt(
|
||||
data.buffer,
|
||||
iv.buffer,
|
||||
key.buffer,
|
||||
);
|
||||
const decValue = await nodeCryptoFunctionService.aesDecrypt(encValue, iv.buffer, key.buffer);
|
||||
expect(Utils.fromBufferToUtf8(decValue)).toBe(value);
|
||||
});
|
||||
});
|
||||
|
||||
describe("aesDecryptFast", () => {
|
||||
it("should successfully decrypt data", async () => {
|
||||
const nodeCryptoFunctionService = new NodeCryptoFunctionService();
|
||||
const iv = Utils.fromBufferToB64(makeStaticByteArray(16).buffer);
|
||||
const symKey = new SymmetricCryptoKey(makeStaticByteArray(32).buffer);
|
||||
const data = "ByUF8vhyX4ddU9gcooznwA==";
|
||||
const params = nodeCryptoFunctionService.aesDecryptFastParameters(data, iv, null, symKey);
|
||||
const decValue = await nodeCryptoFunctionService.aesDecryptFast(params);
|
||||
expect(decValue).toBe("EncryptMe!");
|
||||
});
|
||||
});
|
||||
|
||||
describe("aesDecrypt", () => {
|
||||
it("should successfully decrypt data", async () => {
|
||||
const nodeCryptoFunctionService = new NodeCryptoFunctionService();
|
||||
const iv = makeStaticByteArray(16);
|
||||
const key = makeStaticByteArray(32);
|
||||
const data = Utils.fromB64ToArray("ByUF8vhyX4ddU9gcooznwA==");
|
||||
const decValue = await nodeCryptoFunctionService.aesDecrypt(
|
||||
data.buffer,
|
||||
iv.buffer,
|
||||
key.buffer,
|
||||
);
|
||||
expect(Utils.fromBufferToUtf8(decValue)).toBe("EncryptMe!");
|
||||
});
|
||||
});
|
||||
|
||||
describe("rsaEncrypt", () => {
|
||||
it("should successfully encrypt and then decrypt data", async () => {
|
||||
const nodeCryptoFunctionService = new NodeCryptoFunctionService();
|
||||
const pubKey = Utils.fromB64ToArray(RsaPublicKey);
|
||||
const privKey = Utils.fromB64ToArray(RsaPrivateKey);
|
||||
const value = "EncryptMe!";
|
||||
const data = Utils.fromUtf8ToArray(value);
|
||||
const encValue = await nodeCryptoFunctionService.rsaEncrypt(
|
||||
data.buffer,
|
||||
pubKey.buffer,
|
||||
"sha1",
|
||||
);
|
||||
const decValue = await nodeCryptoFunctionService.rsaDecrypt(encValue, privKey.buffer, "sha1");
|
||||
expect(Utils.fromBufferToUtf8(decValue)).toBe(value);
|
||||
});
|
||||
});
|
||||
|
||||
describe("rsaDecrypt", () => {
|
||||
it("should successfully decrypt data", async () => {
|
||||
const nodeCryptoFunctionService = new NodeCryptoFunctionService();
|
||||
const privKey = Utils.fromB64ToArray(RsaPrivateKey);
|
||||
const data = Utils.fromB64ToArray(
|
||||
"A1/p8BQzN9UrbdYxUY2Va5+kPLyfZXF9JsZrjeEXcaclsnHurdxVAJcnbEqYMP3UXV" +
|
||||
"4YAS/mpf+Rxe6/X0WS1boQdA0MAHSgx95hIlAraZYpiMLLiJRKeo2u8YivCdTM9V5vuAEJwf9Tof/qFsFci3sApdbATkorCT" +
|
||||
"zFOIEPF2S1zgperEP23M01mr4dWVdYN18B32YF67xdJHMbFhp5dkQwv9CmscoWq7OE5HIfOb+JAh7BEZb+CmKhM3yWJvoR/D" +
|
||||
"/5jcercUtK2o+XrzNrL4UQ7yLZcFz6Bfwb/j6ICYvqd/YJwXNE6dwlL57OfwJyCdw2rRYf0/qI00t9u8Iitw==",
|
||||
);
|
||||
const decValue = await nodeCryptoFunctionService.rsaDecrypt(
|
||||
data.buffer,
|
||||
privKey.buffer,
|
||||
"sha1",
|
||||
);
|
||||
expect(Utils.fromBufferToUtf8(decValue)).toBe("EncryptMe!");
|
||||
});
|
||||
});
|
||||
|
||||
describe("rsaExtractPublicKey", () => {
|
||||
it("should successfully extract key", async () => {
|
||||
const nodeCryptoFunctionService = new NodeCryptoFunctionService();
|
||||
const privKey = Utils.fromB64ToArray(RsaPrivateKey);
|
||||
const publicKey = await nodeCryptoFunctionService.rsaExtractPublicKey(privKey.buffer);
|
||||
expect(Utils.fromBufferToB64(publicKey)).toBe(RsaPublicKey);
|
||||
});
|
||||
});
|
||||
|
||||
describe("rsaGenerateKeyPair", () => {
|
||||
testRsaGenerateKeyPair(1024);
|
||||
testRsaGenerateKeyPair(2048);
|
||||
|
||||
// Generating 4096 bit keys is really slow with Forge lib.
|
||||
// Maybe move to something else if we ever want to generate keys of this size.
|
||||
// testRsaGenerateKeyPair(4096);
|
||||
});
|
||||
|
||||
describe("randomBytes", () => {
|
||||
it("should make a value of the correct length", async () => {
|
||||
const nodeCryptoFunctionService = new NodeCryptoFunctionService();
|
||||
const randomData = await nodeCryptoFunctionService.randomBytes(16);
|
||||
expect(randomData.byteLength).toBe(16);
|
||||
});
|
||||
|
||||
it("should not make the same value twice", async () => {
|
||||
const nodeCryptoFunctionService = new NodeCryptoFunctionService();
|
||||
const randomData = await nodeCryptoFunctionService.randomBytes(16);
|
||||
const randomData2 = await nodeCryptoFunctionService.randomBytes(16);
|
||||
expect(
|
||||
randomData.byteLength === randomData2.byteLength && randomData !== randomData2,
|
||||
).toBeTruthy();
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
function testPbkdf2(
|
||||
algorithm: "sha256" | "sha512",
|
||||
regularKey: string,
|
||||
utf8Key: string,
|
||||
unicodeKey: string,
|
||||
) {
|
||||
const regularEmail = "user@example.com";
|
||||
const utf8Email = "üser@example.com";
|
||||
|
||||
const regularPassword = "password";
|
||||
const utf8Password = "pǻssword";
|
||||
const unicodePassword = "😀password🙏";
|
||||
|
||||
it("should create valid " + algorithm + " key from regular input", async () => {
|
||||
const cryptoFunctionService = new NodeCryptoFunctionService();
|
||||
const key = await cryptoFunctionService.pbkdf2(regularPassword, regularEmail, algorithm, 5000);
|
||||
expect(Utils.fromBufferToB64(key)).toBe(regularKey);
|
||||
});
|
||||
|
||||
it("should create valid " + algorithm + " key from utf8 input", async () => {
|
||||
const cryptoFunctionService = new NodeCryptoFunctionService();
|
||||
const key = await cryptoFunctionService.pbkdf2(utf8Password, utf8Email, algorithm, 5000);
|
||||
expect(Utils.fromBufferToB64(key)).toBe(utf8Key);
|
||||
});
|
||||
|
||||
it("should create valid " + algorithm + " key from unicode input", async () => {
|
||||
const cryptoFunctionService = new NodeCryptoFunctionService();
|
||||
const key = await cryptoFunctionService.pbkdf2(unicodePassword, regularEmail, algorithm, 5000);
|
||||
expect(Utils.fromBufferToB64(key)).toBe(unicodeKey);
|
||||
});
|
||||
|
||||
it("should create valid " + algorithm + " key from array buffer input", async () => {
|
||||
const cryptoFunctionService = new NodeCryptoFunctionService();
|
||||
const key = await cryptoFunctionService.pbkdf2(
|
||||
Utils.fromUtf8ToArray(regularPassword).buffer,
|
||||
Utils.fromUtf8ToArray(regularEmail).buffer,
|
||||
algorithm,
|
||||
5000,
|
||||
);
|
||||
expect(Utils.fromBufferToB64(key)).toBe(regularKey);
|
||||
});
|
||||
}
|
||||
|
||||
function testHkdf(
|
||||
algorithm: "sha256" | "sha512",
|
||||
regularKey: string,
|
||||
utf8Key: string,
|
||||
unicodeKey: string,
|
||||
) {
|
||||
const ikm = Utils.fromB64ToArray("criAmKtfzxanbgea5/kelQ==").buffer;
|
||||
|
||||
const regularSalt = "salt";
|
||||
const utf8Salt = "üser_salt";
|
||||
const unicodeSalt = "😀salt🙏";
|
||||
|
||||
const regularInfo = "info";
|
||||
const utf8Info = "üser_info";
|
||||
const unicodeInfo = "😀info🙏";
|
||||
|
||||
it("should create valid " + algorithm + " key from regular input", async () => {
|
||||
const cryptoFunctionService = new NodeCryptoFunctionService();
|
||||
const key = await cryptoFunctionService.hkdf(ikm, regularSalt, regularInfo, 32, algorithm);
|
||||
expect(Utils.fromBufferToB64(key)).toBe(regularKey);
|
||||
});
|
||||
|
||||
it("should create valid " + algorithm + " key from utf8 input", async () => {
|
||||
const cryptoFunctionService = new NodeCryptoFunctionService();
|
||||
const key = await cryptoFunctionService.hkdf(ikm, utf8Salt, utf8Info, 32, algorithm);
|
||||
expect(Utils.fromBufferToB64(key)).toBe(utf8Key);
|
||||
});
|
||||
|
||||
it("should create valid " + algorithm + " key from unicode input", async () => {
|
||||
const cryptoFunctionService = new NodeCryptoFunctionService();
|
||||
const key = await cryptoFunctionService.hkdf(ikm, unicodeSalt, unicodeInfo, 32, algorithm);
|
||||
expect(Utils.fromBufferToB64(key)).toBe(unicodeKey);
|
||||
});
|
||||
|
||||
it("should create valid " + algorithm + " key from array buffer input", async () => {
|
||||
const cryptoFunctionService = new NodeCryptoFunctionService();
|
||||
const key = await cryptoFunctionService.hkdf(
|
||||
ikm,
|
||||
Utils.fromUtf8ToArray(regularSalt).buffer,
|
||||
Utils.fromUtf8ToArray(regularInfo).buffer,
|
||||
32,
|
||||
algorithm,
|
||||
);
|
||||
expect(Utils.fromBufferToB64(key)).toBe(regularKey);
|
||||
});
|
||||
}
|
||||
|
||||
function testHkdfExpand(
|
||||
algorithm: "sha256" | "sha512",
|
||||
b64prk: string,
|
||||
outputByteSize: number,
|
||||
b64ExpectedOkm: string,
|
||||
) {
|
||||
const info = "info";
|
||||
|
||||
it("should create valid " + algorithm + " " + outputByteSize + " byte okm", async () => {
|
||||
const cryptoFunctionService = new NodeCryptoFunctionService();
|
||||
const okm = await cryptoFunctionService.hkdfExpand(
|
||||
Utils.fromB64ToArray(b64prk).buffer,
|
||||
info,
|
||||
outputByteSize,
|
||||
algorithm,
|
||||
);
|
||||
expect(Utils.fromBufferToB64(okm)).toBe(b64ExpectedOkm);
|
||||
});
|
||||
}
|
||||
|
||||
function testHash(
|
||||
algorithm: "sha1" | "sha256" | "sha512" | "md5",
|
||||
regularHash: string,
|
||||
utf8Hash: string,
|
||||
unicodeHash: string,
|
||||
) {
|
||||
const regularValue = "HashMe!!";
|
||||
const utf8Value = "HǻshMe!!";
|
||||
const unicodeValue = "😀HashMe!!!🙏";
|
||||
|
||||
it("should create valid " + algorithm + " hash from regular input", async () => {
|
||||
const cryptoFunctionService = new NodeCryptoFunctionService();
|
||||
const hash = await cryptoFunctionService.hash(regularValue, algorithm);
|
||||
expect(Utils.fromBufferToHex(hash)).toBe(regularHash);
|
||||
});
|
||||
|
||||
it("should create valid " + algorithm + " hash from utf8 input", async () => {
|
||||
const cryptoFunctionService = new NodeCryptoFunctionService();
|
||||
const hash = await cryptoFunctionService.hash(utf8Value, algorithm);
|
||||
expect(Utils.fromBufferToHex(hash)).toBe(utf8Hash);
|
||||
});
|
||||
|
||||
it("should create valid " + algorithm + " hash from unicode input", async () => {
|
||||
const cryptoFunctionService = new NodeCryptoFunctionService();
|
||||
const hash = await cryptoFunctionService.hash(unicodeValue, algorithm);
|
||||
expect(Utils.fromBufferToHex(hash)).toBe(unicodeHash);
|
||||
});
|
||||
|
||||
it("should create valid " + algorithm + " hash from array buffer input", async () => {
|
||||
const cryptoFunctionService = new NodeCryptoFunctionService();
|
||||
const hash = await cryptoFunctionService.hash(
|
||||
Utils.fromUtf8ToArray(regularValue).buffer,
|
||||
algorithm,
|
||||
);
|
||||
expect(Utils.fromBufferToHex(hash)).toBe(regularHash);
|
||||
});
|
||||
}
|
||||
|
||||
function testHmac(algorithm: "sha1" | "sha256" | "sha512", mac: string, fast = false) {
|
||||
it("should create valid " + algorithm + " hmac", async () => {
|
||||
const cryptoFunctionService = new NodeCryptoFunctionService();
|
||||
const value = Utils.fromUtf8ToArray("SignMe!!").buffer;
|
||||
const key = Utils.fromUtf8ToArray("secretkey").buffer;
|
||||
let computedMac: ArrayBuffer = null;
|
||||
if (fast) {
|
||||
computedMac = await cryptoFunctionService.hmacFast(value, key, algorithm);
|
||||
} else {
|
||||
computedMac = await cryptoFunctionService.hmac(value, key, algorithm);
|
||||
}
|
||||
expect(Utils.fromBufferToHex(computedMac)).toBe(mac);
|
||||
});
|
||||
}
|
||||
|
||||
function testCompare(fast = false) {
|
||||
it("should successfully compare two of the same values", async () => {
|
||||
const cryptoFunctionService = new NodeCryptoFunctionService();
|
||||
const a = new Uint8Array(2);
|
||||
a[0] = 1;
|
||||
a[1] = 2;
|
||||
const equal = fast
|
||||
? await cryptoFunctionService.compareFast(a.buffer, a.buffer)
|
||||
: await cryptoFunctionService.compare(a.buffer, a.buffer);
|
||||
expect(equal).toBe(true);
|
||||
});
|
||||
|
||||
it("should successfully compare two different values of the same length", async () => {
|
||||
const cryptoFunctionService = new NodeCryptoFunctionService();
|
||||
const a = new Uint8Array(2);
|
||||
a[0] = 1;
|
||||
a[1] = 2;
|
||||
const b = new Uint8Array(2);
|
||||
b[0] = 3;
|
||||
b[1] = 4;
|
||||
const equal = fast
|
||||
? await cryptoFunctionService.compareFast(a.buffer, b.buffer)
|
||||
: await cryptoFunctionService.compare(a.buffer, b.buffer);
|
||||
expect(equal).toBe(false);
|
||||
});
|
||||
|
||||
it("should successfully compare two different values of different lengths", async () => {
|
||||
const cryptoFunctionService = new NodeCryptoFunctionService();
|
||||
const a = new Uint8Array(2);
|
||||
a[0] = 1;
|
||||
a[1] = 2;
|
||||
const b = new Uint8Array(2);
|
||||
b[0] = 3;
|
||||
const equal = fast
|
||||
? await cryptoFunctionService.compareFast(a.buffer, b.buffer)
|
||||
: await cryptoFunctionService.compare(a.buffer, b.buffer);
|
||||
expect(equal).toBe(false);
|
||||
});
|
||||
}
|
||||
|
||||
function testRsaGenerateKeyPair(length: 1024 | 2048 | 4096) {
|
||||
it(
|
||||
"should successfully generate a " + length + " bit key pair",
|
||||
async () => {
|
||||
const cryptoFunctionService = new NodeCryptoFunctionService();
|
||||
const keyPair = await cryptoFunctionService.rsaGenerateKeyPair(length);
|
||||
expect(keyPair[0] == null || keyPair[1] == null).toBe(false);
|
||||
const publicKey = await cryptoFunctionService.rsaExtractPublicKey(keyPair[1]);
|
||||
expect(Utils.fromBufferToB64(keyPair[0])).toBe(Utils.fromBufferToB64(publicKey));
|
||||
},
|
||||
30000,
|
||||
);
|
||||
}
|
||||
|
||||
function makeStaticByteArray(length: number) {
|
||||
const arr = new Uint8Array(length);
|
||||
for (let i = 0; i < length; i++) {
|
||||
arr[i] = i;
|
||||
}
|
||||
return arr;
|
||||
}
|
||||
@@ -1,13 +0,0 @@
|
||||
import { BaseResponse } from "./baseResponse";
|
||||
|
||||
export class FileResponse implements BaseResponse {
|
||||
object: string;
|
||||
data: Buffer;
|
||||
fileName: string;
|
||||
|
||||
constructor(data: Buffer, fileName: string) {
|
||||
this.object = "file";
|
||||
this.data = data;
|
||||
this.fileName = fileName;
|
||||
}
|
||||
}
|
||||
2289
package-lock.json
generated
2289
package-lock.json
generated
File diff suppressed because it is too large
Load Diff
@@ -94,6 +94,7 @@
|
||||
"@typescript-eslint/parser": "8.54.0",
|
||||
"@yao-pkg/pkg": "5.16.1",
|
||||
"babel-loader": "10.0.0",
|
||||
"clean-webpack-plugin": "4.0.0",
|
||||
"jest-environment-jsdom": "30.2.0",
|
||||
"concurrently": "9.2.0",
|
||||
"copy-webpack-plugin": "13.0.0",
|
||||
@@ -111,9 +112,9 @@
|
||||
"eslint-import-resolver-typescript": "4.4.4",
|
||||
"eslint-plugin-import": "2.32.0",
|
||||
"eslint-plugin-rxjs-angular-x": "0.1.0",
|
||||
"eslint-plugin-rxjs-x": "0.9.1",
|
||||
"eslint-plugin-rxjs-x": "0.8.3",
|
||||
"form-data": "4.0.4",
|
||||
"glob": "13.0.6",
|
||||
"glob": "13.0.0",
|
||||
"html-loader": "5.1.0",
|
||||
"html-webpack-plugin": "5.6.3",
|
||||
"husky": "9.1.7",
|
||||
@@ -123,6 +124,7 @@
|
||||
"jest-preset-angular": "16.0.0",
|
||||
"lint-staged": "16.2.6",
|
||||
"mini-css-extract-plugin": "2.10.0",
|
||||
"minimatch": "5.1.2",
|
||||
"node-forge": "1.3.2",
|
||||
"node-loader": "2.1.0",
|
||||
"prettier": "3.8.1",
|
||||
@@ -135,7 +137,7 @@
|
||||
"tsconfig-paths-webpack-plugin": "4.2.0",
|
||||
"type-fest": "5.4.2",
|
||||
"typescript": "5.9.3",
|
||||
"webpack": "5.105.1",
|
||||
"webpack": "5.104.1",
|
||||
"webpack-cli": "6.0.1",
|
||||
"webpack-merge": "6.0.1",
|
||||
"webpack-node-externals": "3.0.0",
|
||||
|
||||
@@ -68,12 +68,10 @@ export class LdapDirectoryService implements IDirectoryService {
|
||||
}
|
||||
groups = await this.getGroups(groupForce);
|
||||
}
|
||||
} catch (e) {
|
||||
} finally {
|
||||
await this.client.unbind();
|
||||
throw e;
|
||||
}
|
||||
|
||||
await this.client.unbind();
|
||||
return [groups, users];
|
||||
}
|
||||
|
||||
@@ -455,9 +453,8 @@ export class LdapDirectoryService implements IDirectoryService {
|
||||
|
||||
try {
|
||||
await this.client.bind(user, pass);
|
||||
} catch (error) {
|
||||
} catch {
|
||||
await this.client.unbind();
|
||||
throw error;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -5,8 +5,6 @@ import { MessagingService } from "@/jslib/common/src/abstractions/messaging.serv
|
||||
import { OrganizationImportRequest } from "@/jslib/common/src/models/request/organizationImportRequest";
|
||||
import { ApiService } from "@/jslib/common/src/services/api.service";
|
||||
|
||||
import { GroupEntry } from "@/src/models/groupEntry";
|
||||
|
||||
import { getSyncConfiguration } from "../../utils/openldap/config-fixtures";
|
||||
import { DirectoryFactoryService } from "../abstractions/directory-factory.service";
|
||||
import { StateService } from "../abstractions/state.service";
|
||||
@@ -133,134 +131,4 @@ describe("SyncService", () => {
|
||||
|
||||
expect(apiService.postPublicImportDirectory).not.toHaveBeenCalled();
|
||||
});
|
||||
|
||||
describe("nested and circular group handling", () => {
|
||||
function createGroup(
|
||||
name: string,
|
||||
userExternalIds: string[] = [],
|
||||
groupMemberReferenceIds: string[] = [],
|
||||
) {
|
||||
return GroupEntry.fromJSON({
|
||||
name,
|
||||
referenceId: name,
|
||||
externalId: name,
|
||||
userMemberExternalIds: userExternalIds,
|
||||
groupMemberReferenceIds: groupMemberReferenceIds,
|
||||
users: [],
|
||||
});
|
||||
}
|
||||
|
||||
function setupSyncWithGroups(groups: GroupEntry[]) {
|
||||
const mockDirectoryService = mock<LdapDirectoryService>();
|
||||
mockDirectoryService.getEntries.mockResolvedValue([groups, []]);
|
||||
directoryFactory.createService.mockReturnValue(mockDirectoryService);
|
||||
|
||||
stateService.getSync.mockResolvedValue(getSyncConfiguration({ groups: true, users: true }));
|
||||
cryptoFunctionService.hash.mockResolvedValue(new ArrayBuffer(1));
|
||||
stateService.getLastSyncHash.mockResolvedValue("unique hash");
|
||||
singleRequestBuilder.buildRequest.mockReturnValue([
|
||||
{ members: [], groups: [], overwriteExisting: true, largeImport: false },
|
||||
]);
|
||||
}
|
||||
|
||||
it("should handle simple circular reference (A ↔ B) without stack overflow", async () => {
|
||||
const groupA = createGroup("GroupA", ["userA"], ["GroupB"]);
|
||||
const groupB = createGroup("GroupB", ["userB"], ["GroupA"]);
|
||||
setupSyncWithGroups([groupA, groupB]);
|
||||
|
||||
const [groups] = await syncService.sync(true, true);
|
||||
|
||||
const [a, b] = groups;
|
||||
expect(a.userMemberExternalIds).toEqual(new Set(["userA", "userB"]));
|
||||
expect(b.userMemberExternalIds).toEqual(new Set(["userA", "userB"]));
|
||||
});
|
||||
|
||||
it("should handle longer circular chain (A → B → C → A) without stack overflow", async () => {
|
||||
const groupA = createGroup("GroupA", ["userA"], ["GroupB"]);
|
||||
const groupB = createGroup("GroupB", ["userB"], ["GroupC"]);
|
||||
const groupC = createGroup("GroupC", ["userC"], ["GroupA"]);
|
||||
setupSyncWithGroups([groupA, groupB, groupC]);
|
||||
|
||||
const [groups] = await syncService.sync(true, true);
|
||||
|
||||
const allUsers = new Set(["userA", "userB", "userC"]);
|
||||
for (const group of groups) {
|
||||
expect(group.userMemberExternalIds).toEqual(allUsers);
|
||||
}
|
||||
});
|
||||
|
||||
it("should handle diamond structure (A → [B, C] → D)", async () => {
|
||||
const groupA = createGroup("GroupA", ["userA"], ["GroupB", "GroupC"]);
|
||||
const groupB = createGroup("GroupB", ["userB"], ["GroupD"]);
|
||||
const groupC = createGroup("GroupC", ["userC"], ["GroupD"]);
|
||||
const groupD = createGroup("GroupD", ["userD"], []);
|
||||
setupSyncWithGroups([groupA, groupB, groupC, groupD]);
|
||||
|
||||
const [groups] = await syncService.sync(true, true);
|
||||
|
||||
const [a, b, c, d] = groups;
|
||||
expect(a.userMemberExternalIds).toEqual(new Set(["userA", "userB", "userC", "userD"]));
|
||||
expect(b.userMemberExternalIds).toEqual(new Set(["userB", "userD"]));
|
||||
expect(c.userMemberExternalIds).toEqual(new Set(["userC", "userD"]));
|
||||
expect(d.userMemberExternalIds).toEqual(new Set(["userD"]));
|
||||
});
|
||||
|
||||
it("should handle deep nesting with circular reference at leaf", async () => {
|
||||
// Structure: A → B → C → D → B (cycle back to B)
|
||||
const groupA = createGroup("GroupA", ["userA"], ["GroupB"]);
|
||||
const groupB = createGroup("GroupB", ["userB"], ["GroupC"]);
|
||||
const groupC = createGroup("GroupC", ["userC"], ["GroupD"]);
|
||||
const groupD = createGroup("GroupD", ["userD"], ["GroupB"]);
|
||||
setupSyncWithGroups([groupA, groupB, groupC, groupD]);
|
||||
|
||||
const [groups] = await syncService.sync(true, true);
|
||||
|
||||
const [a, b, c, d] = groups;
|
||||
const cycleUsers = new Set(["userB", "userC", "userD"]);
|
||||
expect(a.userMemberExternalIds).toEqual(new Set(["userA", ...cycleUsers]));
|
||||
expect(b.userMemberExternalIds).toEqual(cycleUsers);
|
||||
expect(c.userMemberExternalIds).toEqual(cycleUsers);
|
||||
expect(d.userMemberExternalIds).toEqual(cycleUsers);
|
||||
});
|
||||
|
||||
it("should handle complex structure with multiple cycles and shared members", async () => {
|
||||
// Structure:
|
||||
// A → [B, C]
|
||||
// B → [D, E]
|
||||
// C → [E, F]
|
||||
// D → A (cycle)
|
||||
// E → C (cycle)
|
||||
// F → (leaf)
|
||||
const groupA = createGroup("GroupA", ["userA"], ["GroupB", "GroupC"]);
|
||||
const groupB = createGroup("GroupB", ["userB"], ["GroupD", "GroupE"]);
|
||||
const groupC = createGroup("GroupC", ["userC"], ["GroupE", "GroupF"]);
|
||||
const groupD = createGroup("GroupD", ["userD"], ["GroupA"]);
|
||||
const groupE = createGroup("GroupE", ["userE"], ["GroupC"]);
|
||||
const groupF = createGroup("GroupF", ["userF"], []);
|
||||
setupSyncWithGroups([groupA, groupB, groupC, groupD, groupE, groupF]);
|
||||
|
||||
const [groups] = await syncService.sync(true, true);
|
||||
|
||||
const allUsers = new Set(["userA", "userB", "userC", "userD", "userE", "userF"]);
|
||||
const a = groups.find((g) => g.name === "GroupA");
|
||||
const b = groups.find((g) => g.name === "GroupB");
|
||||
const c = groups.find((g) => g.name === "GroupC");
|
||||
const d = groups.find((g) => g.name === "GroupD");
|
||||
const e = groups.find((g) => g.name === "GroupE");
|
||||
const f = groups.find((g) => g.name === "GroupF");
|
||||
|
||||
// A can reach all groups, so it gets all users
|
||||
expect(a.userMemberExternalIds).toEqual(allUsers);
|
||||
// B reaches D, E, and through cycles reaches everything
|
||||
expect(b.userMemberExternalIds).toEqual(allUsers);
|
||||
// C reaches E (which cycles back to C) and F
|
||||
expect(c.userMemberExternalIds).toEqual(new Set(["userC", "userE", "userF"]));
|
||||
// D cycles to A, which reaches everything
|
||||
expect(d.userMemberExternalIds).toEqual(allUsers);
|
||||
// E cycles to C, picking up C's descendants
|
||||
expect(e.userMemberExternalIds).toEqual(new Set(["userC", "userE", "userF"]));
|
||||
// F is a leaf
|
||||
expect(f.userMemberExternalIds).toEqual(new Set(["userF"]));
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
@@ -189,27 +189,14 @@ export class SyncService {
|
||||
return users == null ? null : users.filter((u) => u.email?.length <= 256);
|
||||
}
|
||||
|
||||
private flattenUsersToGroups(
|
||||
levelGroups: GroupEntry[],
|
||||
allGroups: GroupEntry[],
|
||||
visitedGroups?: Set<string>,
|
||||
): Set<string> {
|
||||
private flattenUsersToGroups(levelGroups: GroupEntry[], allGroups: GroupEntry[]): Set<string> {
|
||||
let allUsers = new Set<string>();
|
||||
if (allGroups == null) {
|
||||
return allUsers;
|
||||
}
|
||||
|
||||
for (const group of levelGroups) {
|
||||
const visited = visitedGroups ?? new Set<string>();
|
||||
|
||||
if (visited.has(group.referenceId)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
visited.add(group.referenceId);
|
||||
|
||||
const childGroups = allGroups.filter((g) => group.groupMemberReferenceIds.has(g.referenceId));
|
||||
const childUsers = this.flattenUsersToGroups(childGroups, allGroups, visited);
|
||||
const childUsers = this.flattenUsersToGroups(childGroups, allGroups);
|
||||
childUsers.forEach((id) => group.userMemberExternalIds.add(id));
|
||||
allUsers = new Set([...allUsers, ...group.userMemberExternalIds]);
|
||||
}
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user