Follow what the live server does with tenants and domains
A run on the production server with throwaway tenants, a role, lists and a domain, all removed, found three things the source reading had not: - Something in a tenant has to be on a domain in that tenant (a list in a tenant on an unassigned domain is invalidForeignKey), while something in no tenant may be on a tenant's domain. The account panel's tenant choice offered every tenant; it offers only the domain's now, and a new account starts in the tenant of the domain it is made on. The domain list reads memberTenantId for it. - A domain created in a tenant puts its DKIM keys there too, and they keep the tenant from being deleted. They are counted with the rest, so Delete is not offered while any remain. - Stalwart lets a domain leave a tenant while the tenant still has accounts on it, stranding them. The panel asks first and refuses while any are there. The refusal to delete a tenant that holds anything was confirmed, as were tenant create, quota pointers, logo and rename. The mock follows the domain rule, filters DKIM keys by tenant, and KNOWN-ISSUES records the run. The non-Enterprise notice is now just "Tenants are a Stalwart Enterprise feature." Two sentences were reworded and one plural added, in all nine catalogues, and the old sentences are gone.
This commit is contained in:
@@ -286,3 +286,17 @@ test("a tenant administrator cannot move anything into a tenant", () => {
|
||||
assert.equal(r.notUpdated?.d4?.type, "invalidPatch");
|
||||
assert.match(r.notUpdated!.d4!.description, /memberTenantId/);
|
||||
});
|
||||
|
||||
test("something in a tenant has to be on a domain in it, and something in none may be anywhere", () => {
|
||||
const dir = make("admin");
|
||||
const outside = dir.handlers["x:MailingList/set"]!({ create: { n: { name: "stray", domainId: "d1", memberTenantId: "t1" } } }) as { notCreated?: Record<string, { type: string; objectId: { object: string } }> };
|
||||
assert.equal(outside.notCreated?.n?.type, "invalidForeignKey");
|
||||
assert.equal(outside.notCreated!.n!.objectId.object, "Domain");
|
||||
const inside = dir.handlers["x:MailingList/set"]!({ create: { n: { name: "team", domainId: "d3", memberTenantId: "t1" } } }) as { created?: Record<string, { id: string }> };
|
||||
assert.ok(inside.created?.n?.id);
|
||||
const none = dir.handlers["x:MailingList/set"]!({ create: { n: { name: "open", domainId: "d3" } } }) as { created?: Record<string, { id: string }> };
|
||||
assert.ok(none.created?.n?.id);
|
||||
const [someone] = (dir.handlers["x:Account/query"]!({ filter: { "@type": "User", domainId: "d1" } }) as { ids: string[] }).ids;
|
||||
const move = dir.handlers["x:Account/set"]!({ update: { [someone!]: { memberTenantId: "t1" } } }) as { notUpdated?: Record<string, { type: string }> };
|
||||
assert.equal(move.notUpdated?.[someone!]?.type, "invalidForeignKey");
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user