UNPKG

@webda/core

Version:

Expose API with Lambda

516 lines 22.3 kB
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