@webda/core
Version:
Expose API with Lambda
516 lines • 22.3 kB
JavaScript
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
return c > 3 && r && Object.defineProperty(target, key, r), r;
};
import { suite, test } from "@testdeck/mocha";
import * as assert from "assert";
import * as sinon from "sinon";
import { WebdaError } from "../errors.js";
import { AclModel } from "../models/aclmodel.js";
import { ModelMapLoaderImplementation } from "../models/relations.js";
import { WebdaTest } from "../test.js";
import InvitationService, { InvitationParameters } from "./invitationservice.js";
class MyCompany extends AclModel {
async canAct(ctx, action) {
if (action === "create") {
return;
}
return super.canAct(ctx, action);
}
}
let InvitationTest = class InvitationTest extends WebdaTest {
getTestConfiguration() {
return process.cwd() + "/test/config-invitation.json";
}
async before() {
await super.before();
this.webda.getApplication().addModel("WebdaDemo/Company", MyCompany);
this.store = this.webda.getService("Companies");
this.store._model = MyCompany;
this.service = this.registerService(new InvitationService(this.webda, "invit", {
model: "Company",
invitationStore: "Invitations",
attribute: "__acl",
mapAttribute: "_companies",
pendingAttribute: "__invitations",
notificationService: "DebugMailer",
mapFields: ["name"],
url: "/companies"
}));
this.invitations = this.webda.getService("Invitations");
this.authentication = this.webda.getService("Authentication");
this.mailer = this.webda.getService("DebugMailer");
await this.service.resolve().init();
}
params() {
let p = new InvitationParameters({
mapFields: "test,test2",
attribute: "_attr"
});
assert.deepStrictEqual(p.mapFields, ["test", "test2"]);
assert.strictEqual(p.pendingAttribute, "_attrPending");
assert.strictEqual(p.multiple, true);
assert.strictEqual(p.authenticationService, "Authentication");
assert.throws(() => new InvitationParameters({
attribute: "plop"
}), /needs to start with a _/);
assert.throws(() => new InvitationParameters({
attribute: "_plop",
pendingAttribute: "bouzouf"
}), /needs to start with a _/);
assert.throws(() => new InvitationParameters({
autoAccept: true,
multiple: false,
fields: "test,test2",
attribute: "_attr"
}), /You cannot have multiple=false with autoAccept=true/);
}
async initNoTemplate() {
let stub = sinon.stub(this.mailer, "hasNotification").callsFake(() => false);
try {
this.service.getParameters().notification = "plop";
await assert.rejects(() => this.service.init(), /Email template should exist/);
}
finally {
stub.restore();
}
}
async inviteOnMissing() {
let ctx = await this.newContext();
await assert.rejects(() => this.execute(ctx, "test.webda.io", "POST", `/companies/unknown/invitations`, {}), WebdaError.NotFound);
}
async inviteOnAclWithAutoAccept() {
this.service.getParameters().autoAccept = true;
this.service.getParameters().notification = "COMPANY_INVITE";
sinon.stub(this.service.notificationService, "sendNotification").callsFake(async () => { });
// New model as owner
let ctx = await this.newContext();
let user = await this.authentication.getUserStore().save({ displayName: "Webda.io Test" });
ctx.getSession().userId = user.getUuid();
const company = await MyCompany.create({ name: "MyTestCompany", __acl: { [user.getUuid()]: "all" } });
// Auto register 2 users
await this.authentication.createUserWithIdent("email", "test1@webda.io");
await this.authentication.createUserWithIdent("email", "test2@webda.io");
const ident1 = await this.authentication.getIdentStore().get(`test1@webda.io_email`);
const ident2 = await this.authentication.getIdentStore().get(`test2@webda.io_email`);
// Add four users to the ACL
// 2 unregistered , 2 registered
await this.execute(ctx, "test.webda.io", "POST", `/companies/${company.getUuid()}/invitations`, {
idents: ["test1@webda.io_email", "test3@webda.io_email", "test4@webda.io_email"],
users: [ident2.getUser(), "unknown"],
metadata: "read"
});
await company.refresh();
assert.deepStrictEqual(company.__acl, {
[ident1.getUser().toString()]: "read",
[ident2.getUser().toString()]: "read",
[user.getUuid()]: "all"
});
let getter = await this.execute(ctx, "test.webda.io", "GET", `/companies/${company.getUuid()}/invitations`);
// @ts-ignore
assert.deepStrictEqual(company.__invitations, {
"ident_test3@webda.io_email": "read",
"ident_test4@webda.io_email": "read"
});
// @ts-ignore
assert.deepStrictEqual(company.__invitations, getter);
assert.deepStrictEqual((await this.invitations.getAll()).map(i => ({
uuid: i.getUuid(),
...i[this.service.getInvitationAttribute(company.getUuid())]
})), [
{
uuid: "test3@webda.io_email_invit",
metadata: "read",
inviter: {
uuid: user.getUuid(),
displayName: "Webda.io Test"
}
},
{
uuid: "test4@webda.io_email_invit",
metadata: "read",
inviter: {
uuid: user.getUuid(),
displayName: "Webda.io Test"
}
}
]);
// Reinviting should be handled and metadata overwritten
await this.execute(ctx, "test.webda.io", "POST", `/companies/${company.getUuid()}/invitations`, {
idents: ["test2@webda.io_email", "test3@webda.io_email", "test4@webda.io_email"],
users: [ident1.getUser()],
metadata: "read,write"
});
await company.refresh();
assert.deepStrictEqual(company.__acl, {
[ident1.getUser().toString()]: "read,write",
[ident2.getUser().toString()]: "read,write",
[user.getUuid()]: "all"
});
let userCheck = await this.authentication.getUserStore().get(ident1.getUser().toString());
assert.deepStrictEqual(userCheck["_companies"], [
{
inviter: {
displayName: "Webda.io Test",
uuid: user.getUuid()
},
metadata: {
name: "MyTestCompany"
},
model: company.getUuid(),
pending: false
}
]);
// @ts-ignore
assert.deepStrictEqual(company.__invitations, {
"ident_test3@webda.io_email": "read,write",
"ident_test4@webda.io_email": "read,write"
});
assert.deepStrictEqual((await this.invitations.getAll()).map(i => ({
uuid: i.getUuid(),
...i[this.service.getInvitationAttribute(company.getUuid())]
})), [
{
uuid: "test3@webda.io_email_invit",
metadata: "read,write",
inviter: {
uuid: user.getUuid(),
displayName: "Webda.io Test"
}
},
{
uuid: "test4@webda.io_email_invit",
metadata: "read,write",
inviter: {
uuid: user.getUuid(),
displayName: "Webda.io Test"
}
}
]);
// Remove 1 unregistered and one registered from the ACL
await this.execute(ctx, "test.webda.io", "DELETE", `/companies/${company.getUuid()}/invitations`, {
idents: ["test1@webda.io_email", "test3@webda.io_email"]
});
await company.refresh();
assert.deepStrictEqual(company.__acl, {
[ident2.getUser().toString()]: "read,write",
[user.getUuid()]: "all"
});
// @ts-ignore
assert.deepStrictEqual(company.__invitations, {
"ident_test4@webda.io_email": "read,write"
});
assert.deepStrictEqual((await this.invitations.getAll()).map(i => ({
uuid: i.getUuid(),
...i[this.service.getInvitationAttribute(company.getUuid())]
})), [
{ uuid: "test3@webda.io_email_invit" },
{
uuid: "test4@webda.io_email_invit",
metadata: "read,write",
inviter: {
uuid: user.getUuid(),
displayName: "Webda.io Test"
}
}
]);
// Missing model
await this.invitations.setAttribute("test4@webda.io_email_invit", "invit_test", "all");
// Register user 3 and 4
await this.authentication.createUserWithIdent("email", "test3@webda.io");
await this.authentication.createUserWithIdent("email", "test4@webda.io");
const ident3 = await this.authentication.getIdentStore().get(`test3@webda.io_email`);
const ident4 = await this.authentication.getIdentStore().get(`test4@webda.io_email`);
await company.refresh();
assert.deepStrictEqual(company.__acl, {
[ident2.getUser().toString()]: "read,write",
[ident4.getUser().toString()]: "read,write",
[user.getUuid()]: "all"
});
// @ts-ignore
assert.deepStrictEqual(company.__invitations, {});
assert.deepStrictEqual((await this.invitations.getAll()).map(i => ({
uuid: i.getUuid(),
metadata: i[this.service.getInvitationAttribute(company.getUuid())]
})), []);
userCheck = await this.authentication.getUserStore().get(ident3.getUser().toString());
assert.deepStrictEqual(userCheck["_companies"] || [], []);
userCheck = await this.authentication.getUserStore().get(ident4.getUser().toString());
assert.deepStrictEqual(userCheck["_companies"], [
{
inviter: {
displayName: "Webda.io Test",
uuid: user.getUuid()
},
metadata: {
name: "MyTestCompany"
},
model: company.getUuid(),
pending: false
}
]);
}
async inviteOnAclWithoutAutoAccept() {
this.service.getParameters().autoAccept = false;
// New model as owner
let ctx = await this.newContext();
let user = await this.authentication.getUserStore().save({
displayName: "Webda.io Test"
});
ctx.getSession().userId = user.getUuid();
const company = await MyCompany.create({ name: "MyTestCompany", __acl: { [user.getUuid()]: "all" } });
// Auto register 2 users
await this.authentication.createUserWithIdent("email", "test1@webda.io");
await this.authentication.createUserWithIdent("email", "test2@webda.io");
const ident1 = await this.authentication.getIdentStore().get(`test1@webda.io_email`);
const ident2 = await this.authentication.getIdentStore().get(`test2@webda.io_email`);
// Add four users to the ACL
// 2 unregistered , 2 registered
await this.execute(ctx, "test.webda.io", "POST", `/companies/${company.getUuid()}/invitations`, {
idents: ["test1@webda.io_email", "test3@webda.io_email", "test4@webda.io_email"],
users: [ident2.getUser()],
metadata: "read"
});
await company.refresh();
assert.deepStrictEqual(company.__acl, {
[user.getUuid()]: "all"
});
// @ts-ignore
assert.deepStrictEqual(company.__invitations, {
[`user_${ident1.getUser()}`]: "read",
[`user_${ident2.getUser()}`]: "read",
"ident_test3@webda.io_email": "read",
"ident_test4@webda.io_email": "read"
});
assert.deepStrictEqual((await this.invitations.getAll()).map(i => ({
uuid: i.getUuid(),
...i[this.service.getInvitationAttribute(company.getUuid())]
})), [
{
uuid: "test3@webda.io_email_invit",
metadata: "read",
inviter: {
uuid: user.getUuid(),
displayName: "Webda.io Test"
}
},
{
uuid: "test4@webda.io_email_invit",
metadata: "read",
inviter: {
uuid: user.getUuid(),
displayName: "Webda.io Test"
}
}
]);
let userCheck = await this.authentication.getUserStore().get(ident1.getUser().toString());
assert.deepStrictEqual(userCheck["_companies"], [
{
inviter: {
displayName: "Webda.io Test",
uuid: user.getUuid()
},
metadata: {
name: "MyTestCompany"
},
model: company.getUuid(),
pending: true
}
]);
userCheck["_companies"] = [
{
model: "Test"
},
...userCheck["_companies"]
];
// @ts-ignore
await userCheck.save("_companies");
// Accepting the invite for user1
let ctx2 = await this.newContext();
ctx2.getSession().userId = ident1.getUser().toString();
await this.execute(ctx2, "test.webda.io", "PUT", `/companies/${company.getUuid()}/invitations`, {
accept: true
});
await company.refresh();
assert.deepStrictEqual(company.__acl, {
[ident1.getUser().toString()]: "read",
[user.getUuid()]: "all"
});
// Reinviting should be handled and metadata overwritten
await this.execute(ctx, "test.webda.io", "POST", `/companies/${company.getUuid()}/invitations`, {
idents: ["test1@webda.io_email", "test2@webda.io_email", "test3@webda.io_email", "test4@webda.io_email"],
metadata: "read,write"
});
await company.refresh();
assert.deepStrictEqual(company.__acl, {
[ident1.getUser().toString()]: "read",
[user.getUuid()]: "all"
});
// @ts-ignore
assert.deepStrictEqual(company.__invitations, {
[`user_${ident2.getUser()}`]: "read,write",
"ident_test3@webda.io_email": "read,write",
"ident_test4@webda.io_email": "read,write"
});
assert.deepStrictEqual((await this.invitations.getAll()).map(i => ({
uuid: i.getUuid(),
...i[this.service.getInvitationAttribute(company.getUuid())]
})), [
{
uuid: "test3@webda.io_email_invit",
metadata: "read,write",
inviter: {
uuid: user.getUuid(),
displayName: "Webda.io Test"
}
},
{
uuid: "test4@webda.io_email_invit",
metadata: "read,write",
inviter: {
uuid: user.getUuid(),
displayName: "Webda.io Test"
}
}
]);
// Remove 1 unregistered and one registered from the ACL
await this.execute(ctx, "test.webda.io", "DELETE", `/companies/${company.getUuid()}/invitations`, {
idents: ["test3@webda.io_email"],
users: [ident1.getUser(), ident2.getUser()]
});
// Ensure double delete will not be an issue
await this.execute(ctx, "test.webda.io", "DELETE", `/companies/${company.getUuid()}/invitations`, {
users: [ident1.getUser(), ident2.getUser()]
});
await company.refresh();
assert.deepStrictEqual(company.__acl, {
[user.getUuid()]: "all"
});
// @ts-ignore
assert.deepStrictEqual(company.__invitations, {
"ident_test4@webda.io_email": "read,write"
});
assert.deepStrictEqual((await this.invitations.getAll()).map(i => ({
uuid: i.getUuid(),
...i[this.service.getInvitationAttribute(company.getUuid())]
})), [
{ uuid: "test3@webda.io_email_invit" },
{
uuid: "test4@webda.io_email_invit",
metadata: "read,write",
inviter: {
uuid: user.getUuid(),
displayName: "Webda.io Test"
}
}
]);
userCheck = await this.authentication.getUserStore().get(ident1.getUser().toString());
assert.deepStrictEqual(userCheck["_companies"], [
{
model: "Test"
}
]);
userCheck = await this.authentication.getUserStore().get(ident2.getUser().toString());
assert.deepStrictEqual(userCheck["_companies"], []);
// Missing model
await this.invitations.setAttribute("test4@webda.io_email_invit", "invit_test", "all");
// Register user 3 and 4
await this.authentication.createUserWithIdent("email", "test3@webda.io");
await this.authentication.createUserWithIdent("email", "test4@webda.io");
await this.authentication.getIdentStore().get(`test3@webda.io_email`);
const ident4 = await this.authentication.getIdentStore().get(`test4@webda.io_email`);
await company.refresh();
assert.deepStrictEqual(company.__acl, {
[user.getUuid()]: "all"
});
// @ts-ignore
assert.deepStrictEqual(company.__invitations, {
"ident_test4@webda.io_email": "read,write"
});
assert.deepStrictEqual((await this.invitations.getAll()).map(i => ({
uuid: i.getUuid(),
...i[this.service.getInvitationAttribute(company.getUuid())]
})), []);
ctx2.getSession().userId = ident4.getUser().toString();
// Force refresh of user as we changed user manually
await ctx2.getCurrentUser(true);
ctx2.getCurrentUser = async () => {
let user = await ident4.getUser().get();
user.getIdents = () => [
new ModelMapLoaderImplementation(ident4.__class, ident4, user)
];
return user;
};
await this.execute(ctx2, "test.webda.io", "PUT", `/companies/${company.getUuid()}/invitations`, {
accept: true
});
await company.refresh();
assert.deepStrictEqual(company.__acl, {
[user.getUuid()]: "all",
[ident4.getUser().toString()]: "read,write"
});
// @ts-ignore
assert.deepStrictEqual(company.__invitations, {});
}
async invitationDeletedModel() {
this.service.getParameters().autoAccept = false;
// New model as owner
let ctx = await this.newContext();
let user = await this.authentication.getUserStore().save({
displayName: "Webda.io Test"
});
ctx.getSession().userId = user.getUuid();
const company = await MyCompany.create({ name: "MyTestCompany", __acl: { [user.getUuid()]: "all" } });
// Auto register 2 users
await this.authentication.createUserWithIdent("email", "test1@webda.io");
const ident1 = await this.authentication.getIdentStore().get(`test1@webda.io_email`);
// Add two users to the ACL
// 1 unregistered , 1 registered
await this.execute(ctx, "test.webda.io", "POST", `/companies/${company.getUuid()}/invitations`, {
idents: ["test2@webda.io_email"],
users: [ident1.getUser()],
metadata: "read"
});
await company.delete();
let checkUser = await this.authentication.getUserStore().get(ident1.getUser().toString());
assert.strictEqual(checkUser["_companies"].length, 1);
// Accepting the invite for user1
let ctx2 = await this.newContext();
ctx2.getSession().userId = ident1.getUser().toString();
// It should be removed and get a 410 error code
await assert.rejects(() => this.execute(ctx2, "test.webda.io", "PUT", `/companies/${company.getUuid()}/invitations`, {
accept: true
}), WebdaError.Gone);
await checkUser.refresh();
assert.strictEqual(checkUser["_companies"].length, 0);
// Register pending one
await this.authentication.createUserWithIdent("email", "test2@webda.io");
const ident2 = await this.authentication.getIdentStore().get(`test2@webda.io_email`);
checkUser = await this.authentication.getUserStore().get(ident2.getUser().toString());
assert.strictEqual(checkUser["_companies"].length, 0);
}
};
__decorate([
test
], InvitationTest.prototype, "params", null);
__decorate([
test
], InvitationTest.prototype, "initNoTemplate", null);
__decorate([
test
], InvitationTest.prototype, "inviteOnMissing", null);
__decorate([
test
], InvitationTest.prototype, "inviteOnAclWithAutoAccept", null);
__decorate([
test
], InvitationTest.prototype, "inviteOnAclWithoutAutoAccept", null);
__decorate([
test
], InvitationTest.prototype, "invitationDeletedModel", null);
InvitationTest = __decorate([
suite
], InvitationTest);
//# sourceMappingURL=invitationservice.spec.js.map