feat: init

This commit is contained in:
montaghanmy
2023-03-23 11:03:16 +01:00
commit 10fe6f78d1
11518 changed files with 509786 additions and 0 deletions
@@ -0,0 +1,272 @@
import { afterAll, beforeAll, describe, expect, it as _it, it } from "@jest/globals";
import { init, TestPlatform } from "../setup";
import { TestDbService } from "../utils.prepare.db";
import { v1 as uuidv1 } from "uuid";
import gr from "../../../src/services/global-resolver";
export const itRemote = (name: string, cb: (a: any) => void) => {
_it(name, async done => {
if (gr.services.console.consoleType === "remote") {
cb(done);
} else {
console.warn(`[skipped]: ${name} (console-mode only)`);
done();
}
});
};
describe("The console API auth", () => {
const loginUrl = "/internal/services/console/v1/login";
const tokenRefreshUrl = "/internal/services/console/v1/token";
let platform: TestPlatform;
let testDbService: TestDbService;
const companyId = uuidv1();
const firstEmail = "superman@email.com";
const firstUserPassword = "superPassw0rd";
beforeAll(async ends => {
platform = await init({
services: [
"database",
"message-queue",
"search",
"applications",
"webserver",
"user",
"workspaces",
"auth",
"console",
"storage",
"counter",
"statistics",
"platform-services",
],
});
await platform.database.getConnector().init();
testDbService = await TestDbService.getInstance(platform);
await testDbService.createCompany(companyId);
const ws0pk = { id: uuidv1(), company_id: companyId };
// const ws1pk = { id: uuidv1(), company_id: companyId };
await testDbService.createWorkspace(ws0pk);
// await testDbService.createWorkspace(ws1pk);
await testDbService.createUser([ws0pk], {
companyRole: "member",
workspaceRole: "moderator",
email: firstEmail,
firstName: "superman",
password: firstUserPassword,
});
// await testDbService.createUser([ws0pk], "member", "member");
// await testDbService.createUser([ws1pk], "member", "member", emailForExistedUser);
await new Promise(r => setTimeout(r, 1000));
ends();
});
afterAll(async ends => {
await platform.tearDown();
ends();
});
describe("Common checks", () => {
it("should 400 when required params are missing ", async done => {
const response = await platform.app.inject({
method: "POST",
url: `${loginUrl}`,
payload: {
email: "",
password: "",
remote_access_token: "",
},
});
expect(response.statusCode).toBe(400);
expect(response.json()).toMatchObject({
statusCode: 400,
error: "Bad Request",
message: "remote_access_token or email+password are required",
});
done();
});
});
describe("Auth using token", () => {
itRemote("should 403 when token is invalid", async done => {
const response = await platform.app.inject({
method: "POST",
url: `${loginUrl}`,
payload: {
remote_access_token: "12345",
},
});
expect(response.json()).toMatchObject({
error: "Forbidden",
message: "Bad access token credentials",
statusCode: 403,
});
expect(response.statusCode).toBe(403);
done();
});
itRemote("should 200 when token is valid", async done => {
const response = await platform.app.inject({
method: "POST",
url: `${loginUrl}`,
payload: {
email: "",
password: "",
remote_access_token: "a550c8b8b942bd92e447271343ac6b29",
},
});
expect(response.json()).toMatchObject({
access_token: {
time: expect.any(Number),
expiration: expect.any(Number),
refresh_expiration: expect.any(Number),
value: expect.any(String),
refresh: expect.any(String),
type: "Bearer",
},
});
expect(response.statusCode).toBe(200);
done();
});
});
describe("Auth using email/password", () => {
it("should 403 when user doesn't exists", async done => {
const response = await platform.app.inject({
method: "POST",
url: `${loginUrl}`,
payload: {
email: "randomEmail",
password: "randomPass",
},
});
expect(response.statusCode).toBe(403);
expect(response.json()).toMatchObject({
error: "Forbidden",
message: "User doesn't exists",
statusCode: 403,
});
done();
});
it("should 403 when password doesn't match", async done => {
const user = testDbService.users[0];
const response = await platform.app.inject({
method: "POST",
url: `${loginUrl}`,
payload: {
email: user.email_canonical,
password: "randomPass",
},
});
expect(response.statusCode).toBe(403);
expect(response.json()).toMatchObject({
error: "Forbidden",
message: "Password doesn't match",
statusCode: 403,
});
done();
});
it("should 200 when credentials is valid", async done => {
const user = testDbService.users[0];
const response = await platform.app.inject({
method: "POST",
url: `${loginUrl}`,
payload: {
email: user.email_canonical,
password: firstUserPassword,
},
});
expect(response.statusCode).toBe(200);
expect(response.json()).toMatchObject({
access_token: {
time: expect.any(Number),
expiration: expect.any(Number),
refresh_expiration: expect.any(Number),
value: expect.any(String),
refresh: expect.any(String),
type: "Bearer",
},
});
done();
});
});
describe("Token renewal", () => {
it("should 200 when refresh from access_token", async done => {
const user = testDbService.users[0];
const firstResponse = await platform.app.inject({
method: "POST",
url: `${loginUrl}`,
payload: {
email: user.email_canonical,
password: firstUserPassword,
},
});
const firstRes = firstResponse.json().access_token;
expect(firstRes.value).toBeTruthy();
setTimeout(async () => {
const response = await platform.app.inject({
method: "POST",
url: `${tokenRefreshUrl}`,
headers: {
authorization: `Bearer ${firstRes.value}`,
},
});
const secondRes = response.json().access_token;
expect(secondRes.expiration).toBeGreaterThan(firstRes.expiration);
expect(secondRes.refresh_expiration).toBeGreaterThan(firstRes.refresh_expiration);
done();
}, 2000);
});
it("should 200 when refresh from refresh_token", async done => {
const user = testDbService.users[0];
const firstResponse = await platform.app.inject({
method: "POST",
url: `${loginUrl}`,
payload: {
email: user.email_canonical,
password: firstUserPassword,
},
});
const firstRes = firstResponse.json().access_token;
expect(firstRes.refresh).toBeTruthy();
setTimeout(async () => {
const response = await platform.app.inject({
method: "POST",
url: `${tokenRefreshUrl}`,
headers: {
authorization: `Bearer ${firstRes.refresh}`,
},
});
const secondRes = response.json().access_token;
expect(secondRes.expiration).toBeGreaterThan(firstRes.expiration);
expect(secondRes.refresh_expiration).toBeGreaterThan(firstRes.refresh_expiration);
done();
}, 2000);
});
});
});
@@ -0,0 +1,545 @@
import { afterAll, beforeAll, describe, expect, it as _it } from "@jest/globals";
import { init, TestPlatform } from "../setup";
import { TestDbService } from "../utils.prepare.db";
import { v1 as uuidv1 } from "uuid";
import { sign as cryptoSign } from "crypto";
import gr from "../../../src/services/global-resolver";
import { ConsoleServiceImpl } from "../../../src/services/console/service";
/*
THIS TESTS RUNS ONLY FOR THE CONSOLE-MODE (CONSOLE TYPE: REMOTE)
*/
export const it = (name: string, cb: (a: any) => void) => {
_it(name, async done => {
if (gr.services.console.consoleType === "remote") {
cb(done);
} else {
console.warn(`[skipped]: ${name} (console-mode only)`);
done();
}
});
};
describe("The console API hooks", () => {
const url = "/internal/services/console/v1/hook";
let platform: TestPlatform;
let testDbService: TestDbService;
const companyId = uuidv1();
const firstEmail = "superman@email.com";
const secondEmail = "C.o.n.sole_created-user@email.com";
const thirdEmail = "superman@someogherservice.com";
const secret = "ohquoo1fohzeigitochaJeepoowug4Yuqueite6etojieg1oowaeraeshiW8ku8g";
beforeAll(async ends => {
platform = await init({
services: [
"database",
"message-queue",
"webserver",
"search",
"user",
"workspaces",
"auth",
"console",
"applications",
"storage",
"counter",
"statistics",
"platform-services",
],
});
await platform.database.getConnector().init();
testDbService = await TestDbService.getInstance(platform);
await testDbService.createCompany(companyId);
const ws0pk = { id: uuidv1(), company_id: companyId };
await testDbService.createWorkspace(ws0pk);
await testDbService.createUser([ws0pk], {
companyRole: "member",
workspaceRole: "moderator",
username: "superman",
});
const console = platform.platform.getProvider<ConsoleServiceImpl>("console");
ends();
});
afterAll(async ends => {
await platform.tearDown();
ends();
});
const getPayload = (type: string, content: Record<any, any>) => {
const data = {
content: content,
type: type,
} as any;
const sign = cryptoSign(
"RSA-SHA512",
Buffer.from(JSON.stringify(data)),
"-----BEGIN PRIVATE KEY-----\nMIIEuwIBADANBgkqhkiG9w0BAQEFAASCBKUwggShAgEAAoIBAQD15kALIEHoe1bt\nADG/oOqHLRgnzNoiGl8aQ6LD/9c4F5+IVP9gPxGm26haSMW2Z9doJeTucvV8syQV\nbdwc9z0NUhNhFG1RLsj0+ePgpuBfKv+uzEICrRedP7wsmWC37K1NmGZ+LzO21oeu\nLO0L39kNk+qspJnqqx8PIfUmeQ6DDkEKW/J0ISeOsBOetKiJC2n5F4Fkifh1Bq2T\nsFfW9Tz47hfLAKkNUyoulBbqX/xViUhlhFb59sxhoMesCL/VJf7OmTLvryXBW/TU\nCYFssAZXXSWOOzc2k+X2VX3QslKfCHsnCO75I+FPFd9YtFWKlaHeq36ZHlYxnYqp\nRcdixzhjAgMBAAECggEANtvoe9L1gUVLDlLVxnfC+udflTmJjMQvZW+jd3Czdisn\nB0ZXNwS7DmvA8mt72IbwMqcJnPz+sZRRv4oj6j5qW3dtJWJmRQ9X+/doFG2GbxTr\nt/aP34L4WremZpjNUBs4SrBuZUZolijkWkJhnB2Tkgjm+R87y3Pj2P9tbujhCPGM\nMQf+s5lOh/AXDyqYGyEJAZBJT3DevrB9Cl3uhYWZ0fFUz4hwATeB0Va8YT8ZJea2\nXwajg/NnOOpdSGVgv0+7zhPYvkvg8bMZeH24VxYkAfdww8vANPuk4wUwDvnh39+Q\nI4uHQGXgjf8SJ5Z7G7A5Q4r7Ma4drJDbCOfNTi84+QKBgQD+ar48b7c5ffMT/ta7\nGUfMiHCjLfauHt/1f1CkFN1OpJW2ZrS34jYusqBXos32X2gx+wsOGtzOrhkkpvgp\nL7jaZmUnQTwfn6Sx4Duq+LVVMH/uj+W/Zj24AKnoylzM9XC6D2kwKAfHs4Mg6+fe\no6VRBR/yw01ShR+YDVAEN0B7ZwKBgQD3bfCIlp1DpTjFKEBFaC4jRNJPaf8OLt/U\nYHOBwwltb406I4s13M3A1N74Btk5ycx6n/a6RHIGB6+E2xn9AnYI51M/+n9vBLPc\nnnqjOZP/7FdK7qL/g4JtXae/CyroXYaYXUNsdJttQC62QRW+xhp6fYxWt/nAcc9R\nvXmninx5pQJ/CPG3vmgvCNZktU9APVOmMoqZayMyiOyM8xSGwT36ick/eioiMFTD\nkuC0wl/23bJ890TcHqLTIHD+cUttbgU/em4fIEIq2vHB2H8JmfkkZtpNpRVp/lCZ\n2t4rGwQCPzJhxCjGiereWyb0dTPV8v3N0gtcFCzJix0i/zV4mq1WlwKBgGfV1F6N\nznun57YdmTNHcC1O4W+ATRA3rakjvPWU0u0BJmRirDYzbolhDB1MSncM7+n6HYG3\n3Z4YNZlslXBvSveblH1B8560e4K3Y0IClNCO72c71F2kY+Tfq9jpp90R+r0QTo5C\nNUPY7oF/uM9xtYT4ESAHXyFa4aUs/dPIs0odAoGBAKYqeAsbLIsb2ruMkeH5itbe\nxdgVHZ8d2Pxk1h+52SGyptuBzlt7c6Gb3KNxpIc61tZklOn5yj+QmJHN82rXGdIE\nCkdrkEmqZU52X2OInozV1Py8L7akH9wijzy5ULWqxapIE2ItnPkgcC7+x6vglkfd\nI0VcGHm8cgqCpzRaIZjH\n-----END PRIVATE KEY-----",
);
data.signature = sign.toString("base64");
return data;
};
describe("Common checks", () => {
it("should 404 when not POST ", async done => {
const response = await platform.app.inject({
method: "GET",
url: `${url}`,
});
expect(response.statusCode).toBe(404);
done();
});
it("should 400 when secret key is missing", async done => {
const response = await platform.app.inject({
method: "POST",
url: `${url}`,
payload: getPayload("a", {}),
});
expect(response.statusCode).toBe(400);
expect(response.json()).toMatchObject({
statusCode: 400,
error: "Bad Request",
message: "querystring should have required property 'secret_key'",
});
done();
});
it("should 403 when secret key is not valid ", async done => {
const response = await platform.app.inject({
method: "POST",
url: `${url}?secret_key=wrongOne`,
payload: getPayload("a", {}),
});
expect(response.statusCode).toBe(403);
expect(response.json()).toMatchObject({
statusCode: 403,
error: "Forbidden",
message: "Wrong secret",
});
done();
});
it("should 501 when type is not implemented", async done => {
const response = await platform.app.inject({
method: "POST",
url: `${url}?secret_key=${secret}`,
payload: getPayload("unknown_type", {}),
});
expect(response.statusCode).toBe(501);
done();
});
});
describe("User related hooks", () => {
describe("User created/updated", () => {
it("should 200 when updated existing user", async done => {
const user = testDbService.users[0];
const response = await platform.app.inject({
method: "POST",
url: `${url}?secret_key=${secret}`,
payload: getPayload("user_updated", {
user: {
_id: user.identity_provider_id,
roles: [
{ targetCode: companyId, roleCode: "owner", applications: [{ code: "twake" }] },
],
email: firstEmail,
firstName: "firstName",
lastName: "lastName",
isVerified: true,
preference: {
locale: "en",
timeZone: 2,
},
avatar: {
type: "unknown",
value: "123456.jpg",
},
},
}),
});
expect(response.statusCode).toBe(200);
const updatedUser = await testDbService.getUserFromDb({
id: user.id,
});
expect(updatedUser).toMatchObject({
id: user.id,
email_canonical: firstEmail,
first_name: "firstName",
last_name: "lastName",
mail_verified: true,
timezone: 2,
language: "en",
picture:
gr.services.console.consoleOptions.url.replace(/\/$/, "") + "/avatars/123456.jpg",
});
const userRoles = await testDbService.getCompanyUser(companyId, updatedUser.id);
expect(userRoles).toEqual(
expect.objectContaining({
role: "owner",
}),
);
done();
});
it("should 200 when creating new user", async done => {
const newUserConsoleId = String(testDbService.rand());
const response = await platform.app.inject({
method: "POST",
url: `${url}?secret_key=${secret}`,
payload: getPayload("user_updated", {
user: {
_id: newUserConsoleId,
roles: [
{ targetCode: companyId, roleCode: "admin", applications: [{ code: "twake" }] },
],
email: secondEmail,
firstName: "consoleFirst",
lastName: "consoleSecond",
isVerified: true,
preference: {
locale: "ru",
timeZone: 3,
},
avatar: {
type: "unknown",
value: "5678.jpg",
},
},
}),
});
expect(response.statusCode).toBe(200);
const updatedUser = await testDbService.getUserFromDb({
identity_provider_id: newUserConsoleId,
});
expect(updatedUser).toMatchObject({
first_name: "consoleFirst",
last_name: "consoleSecond",
mail_verified: true,
timezone: 3,
language: "ru",
creation_date: expect.any(String),
deleted: false,
email_canonical: secondEmail.toLocaleLowerCase(),
identity_provider: "console",
identity_provider_id: newUserConsoleId,
username_canonical: "consolecreateduser",
picture: gr.services.console.consoleOptions.url.replace(/\/$/, "") + "/avatars/5678.jpg",
});
const userRoles = await testDbService.getCompanyUser(companyId, updatedUser.id);
expect(userRoles).toEqual(
expect.objectContaining({
role: "moderator",
}),
);
done();
});
it("should 200 when creating new user with same username (generating new one)", async done => {
const newUserConsoleId = String(testDbService.rand());
const response = await platform.app.inject({
method: "POST",
url: `${url}?secret_key=${secret}`,
payload: getPayload("user_updated", {
user: {
_id: newUserConsoleId,
roles: [
{ targetCode: companyId, roleCode: "member", applications: [{ code: "twake" }] },
],
email: thirdEmail,
firstName: "superman",
lastName: "superman-lastname",
isVerified: true,
preference: {
locale: "ru",
timeZone: 3,
},
avatar: {
type: "unknown",
value: "5679.jpg",
},
},
}),
});
expect(response.statusCode).toBe(200);
const updatedUser = await testDbService.getUserFromDb({
identity_provider_id: newUserConsoleId,
});
expect(updatedUser).toMatchObject({
first_name: "superman",
last_name: "superman-lastname",
mail_verified: true,
timezone: 3,
language: "ru",
creation_date: expect.any(String),
deleted: false,
email_canonical: thirdEmail.toLocaleLowerCase(),
identity_provider: "console",
identity_provider_id: newUserConsoleId,
username_canonical: "superman1",
picture: gr.services.console.consoleOptions.url.replace(/\/$/, "") + "/avatars/5679.jpg",
});
const userRoles = await testDbService.getCompanyUser(companyId, updatedUser.id);
expect(userRoles).toEqual(
expect.objectContaining({
role: "member",
}),
);
done();
});
it("should 400 when creating user with email that already exists", async done => {
const newUserConsoleId = String(testDbService.rand());
const response = await platform.app.inject({
method: "POST",
url: `${url}?secret_key=${secret}`,
payload: getPayload("user_updated", {
user: {
_id: newUserConsoleId,
email: firstEmail,
},
}),
});
expect(response.statusCode).toBe(400);
expect(response.json()).toMatchObject({
error: "Console user not created because email already exists",
});
done();
});
});
describe("User removed", () => {
it("should 200 when deleting", async done => {
const company = testDbService.company;
let users = await testDbService.getCompanyUsers(company.id);
let user = users.find(a => a.username_canonical == "consolecreateduser");
expect(user).toBeTruthy();
const response = await platform.app.inject({
method: "POST",
url: `${url}?secret_key=${secret}`,
payload: getPayload("company_user_deactivated", {
company: { code: company.identity_provider_id },
user: {
_id: user.identity_provider_id,
},
}),
});
expect(response.statusCode).toBe(200);
users = await testDbService.getCompanyUsers(company.id);
user = users.find(a => a.username_canonical == "consolecreateduser");
expect(user).toBeFalsy();
done();
});
it("should 400 when user not found", async done => {
const company = testDbService.company;
const response = await platform.app.inject({
method: "POST",
url: `${url}?secret_key=${secret}`,
payload: getPayload("company_user_deactivated", {
company: { code: company.identity_provider_id },
user: {
_id: 123456789,
},
}),
});
expect(response.statusCode).toBe(400);
done();
});
});
});
describe("Company related hooks", () => {
describe("Company added", () => {
it("should 200 when company created", async done => {
const newCompanyCode = String(testDbService.rand());
const response = await platform.app.inject({
method: "POST",
url: `${url}?secret_key=${secret}`,
payload: getPayload("company_created", {
company: {
code: newCompanyCode,
stats: "stats",
plan: { name: "plan name", limits: {} },
value: "value",
details: {
logo: "logo",
avatar: {
value: "avatar.jpg",
type: "type",
},
name: "company name",
},
},
}),
});
expect(response.statusCode).toBe(200);
const createdCompany = await testDbService.getCompanyFromDbByCode(newCompanyCode);
expect(createdCompany).toEqual(
expect.objectContaining({
id: expect.any(String),
name: "company name",
plan: { name: "plan name", limits: {} },
stats: "stats",
logo: "logo",
dateAdded: expect.any(Number),
identity_provider: "console",
identity_provider_id: newCompanyCode,
// details:
}),
);
done();
});
});
describe("Company updated", () => {
it("should 200 when company updated", async done => {
const company = testDbService.company;
expect(company).toBeTruthy();
expect(company.identity_provider_id).toBeTruthy();
const response = await platform.app.inject({
method: "POST",
url: `${url}?secret_key=${secret}`,
payload: getPayload("company_updated", {
company: {
code: company.identity_provider_id,
stats: "stats",
plan: { name: "plan name", limits: {} },
value: "value",
details: {
logo: "logo",
avatar: {
value: "avatar.jpg",
type: "type",
},
name: "new company name",
},
},
}),
});
expect(response.statusCode).toBe(200);
const createdCompany = await testDbService.getCompanyFromDb(company.id);
expect(createdCompany).toEqual(
expect.objectContaining({
id: company.id,
name: "new company name",
plan: { name: "plan name", limits: {} },
stats: "stats",
logo: "logo",
dateAdded: expect.any(Number),
identity_provider: "console",
identity_provider_id: company.identity_provider_id,
// details:
}),
);
done();
});
});
describe("Plan updated", () => {
it("should 200 when plan updated", async done => {
const company = testDbService.company;
expect(company).toBeTruthy();
expect(company.identity_provider_id).toBeTruthy();
const response = await platform.app.inject({
method: "POST",
url: `${url}?secret_key=${secret}`,
payload: getPayload("plan_updated", {
company: {
code: company.identity_provider_id,
plan: { name: "another plan name", limits: {} },
},
}),
});
expect(response.statusCode).toBe(200);
const createdCompany = await testDbService.getCompanyFromDb(company.id);
expect(createdCompany).toEqual(
expect.objectContaining({
id: company.id,
name: "new company name",
plan: { name: "another plan name", limits: {} },
stats: "stats",
logo: "logo",
dateAdded: expect.any(Number),
identity_provider: "console",
identity_provider_id: company.identity_provider_id,
// details:
}),
);
done();
});
});
describe("Company removed", () => {
it("should 200 when company removed", async done => {
const company = testDbService.company;
expect(company).toBeTruthy();
expect(company.identity_provider_id).toBeTruthy();
const response = await platform.app.inject({
method: "POST",
url: `${url}?secret_key=${secret}`,
payload: getPayload("company_deleted", {
company: {
code: company.identity_provider_id,
},
}),
});
expect(response.statusCode).toBe(200);
const deletedCompany = await testDbService.getCompanyFromDb(company.id);
expect(deletedCompany).toBeFalsy();
done();
});
});
});
});