fix: visible groups (#2729)
* updated readme to give some light testing instructions * updated tests to accept new behavior for group memberships * use test factories in more places * add debug logs for mailer events in development
This commit is contained in:
parent
8a76dd49a0
commit
ec5e3120d2
|
@ -101,6 +101,13 @@ For contributing features and fixes you can quickly get an environment running u
|
||||||
1. Ensure that the bot token scope contains at least `users:read`
|
1. Ensure that the bot token scope contains at least `users:read`
|
||||||
1. Run `make up`. This will download dependencies, build and launch a development version of Outline
|
1. Run `make up`. This will download dependencies, build and launch a development version of Outline
|
||||||
|
|
||||||
|
### Testing
|
||||||
|
|
||||||
|
The `Makefile` has other useful scripts, including some test automation.
|
||||||
|
|
||||||
|
1. To run the entire test suite, run `make test`
|
||||||
|
1. During development, it's often useful, to re-run some tests every time a file is changed. Use `make watch` to start the test daemon and follow the instructions in the console
|
||||||
|
|
||||||
# Contributing
|
# Contributing
|
||||||
|
|
||||||
Outline is built and maintained by a small team – we'd love your help to fix bugs and add features!
|
Outline is built and maintained by a small team – we'd love your help to fix bugs and add features!
|
||||||
|
|
|
@ -204,12 +204,18 @@ export class Mailer {
|
||||||
};
|
};
|
||||||
|
|
||||||
signin = async (opts: { to: string, token: string, teamUrl: string }) => {
|
signin = async (opts: { to: string, token: string, teamUrl: string }) => {
|
||||||
|
const signInLink = signinEmailText(opts);
|
||||||
|
|
||||||
|
if (process.env.NODE_ENV === "development") {
|
||||||
|
Logger.debug("email", `Sign-In link: ${signInLink}`);
|
||||||
|
}
|
||||||
|
|
||||||
this.sendMail({
|
this.sendMail({
|
||||||
to: opts.to,
|
to: opts.to,
|
||||||
title: "Magic signin link",
|
title: "Magic signin link",
|
||||||
previewText: "Here’s your link to signin to Outline.",
|
previewText: "Here’s your link to signin to Outline.",
|
||||||
html: <SigninEmail {...opts} />,
|
html: <SigninEmail {...opts} />,
|
||||||
text: signinEmailText(opts),
|
text: signInLink,
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -12,12 +12,10 @@ allow(User, "createGroup", Team, (actor, team) => {
|
||||||
});
|
});
|
||||||
|
|
||||||
allow(User, "read", Group, (actor, group) => {
|
allow(User, "read", Group, (actor, group) => {
|
||||||
|
// for the time being, we're going to let everyone on the team see every group
|
||||||
|
// we may need to make this more granular in the future
|
||||||
if (!group || actor.teamId !== group.teamId) return false;
|
if (!group || actor.teamId !== group.teamId) return false;
|
||||||
if (actor.isAdmin) return true;
|
|
||||||
if (group.groupMemberships.filter((gm) => gm.userId === actor.id).length) {
|
|
||||||
return true;
|
return true;
|
||||||
}
|
|
||||||
return false;
|
|
||||||
});
|
});
|
||||||
|
|
||||||
allow(User, ["update", "delete"], Group, (actor, group) => {
|
allow(User, ["update", "delete"], Group, (actor, group) => {
|
||||||
|
|
|
@ -1059,7 +1059,7 @@ describe("#documents.search", () => {
|
||||||
});
|
});
|
||||||
|
|
||||||
it("should strip junk from search term", async () => {
|
it("should strip junk from search term", async () => {
|
||||||
const { user } = await seed();
|
const user = await buildUser();
|
||||||
const firstResult = await buildDocument({
|
const firstResult = await buildDocument({
|
||||||
title: "search term",
|
title: "search term",
|
||||||
text: "this is some random text of the document body",
|
text: "this is some random text of the document body",
|
||||||
|
@ -1137,7 +1137,7 @@ describe("#documents.search", () => {
|
||||||
});
|
});
|
||||||
|
|
||||||
it("should not return draft documents created by other users", async () => {
|
it("should not return draft documents created by other users", async () => {
|
||||||
const { user } = await seed();
|
const user = await buildUser();
|
||||||
await buildDocument({
|
await buildDocument({
|
||||||
title: "search term",
|
title: "search term",
|
||||||
text: "search term",
|
text: "search term",
|
||||||
|
@ -1176,7 +1176,7 @@ describe("#documents.search", () => {
|
||||||
});
|
});
|
||||||
|
|
||||||
it("should return archived documents if chosen", async () => {
|
it("should return archived documents if chosen", async () => {
|
||||||
const { user } = await seed();
|
const user = await buildUser();
|
||||||
const document = await buildDocument({
|
const document = await buildDocument({
|
||||||
title: "search term",
|
title: "search term",
|
||||||
text: "search term",
|
text: "search term",
|
||||||
|
@ -1230,7 +1230,11 @@ describe("#documents.search", () => {
|
||||||
});
|
});
|
||||||
|
|
||||||
it("should return documents for a specific private collection", async () => {
|
it("should return documents for a specific private collection", async () => {
|
||||||
const { user, collection } = await seed();
|
const user = await buildUser();
|
||||||
|
const collection = await buildCollection({
|
||||||
|
teamId: user.teamId,
|
||||||
|
});
|
||||||
|
|
||||||
collection.permission = null;
|
collection.permission = null;
|
||||||
await collection.save();
|
await collection.save();
|
||||||
|
|
||||||
|
|
|
@ -33,13 +33,6 @@ router.post("groups.list", auth(), pagination(), async (ctx) => {
|
||||||
limit: ctx.state.pagination.limit,
|
limit: ctx.state.pagination.limit,
|
||||||
});
|
});
|
||||||
|
|
||||||
if (!user.isAdmin) {
|
|
||||||
groups = groups.filter(
|
|
||||||
(group) =>
|
|
||||||
group.groupMemberships.filter((gm) => gm.userId === user.id).length
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
ctx.body = {
|
ctx.body = {
|
||||||
pagination: ctx.state.pagination,
|
pagination: ctx.state.pagination,
|
||||||
data: {
|
data: {
|
||||||
|
|
|
@ -203,7 +203,7 @@ describe("#groups.info", () => {
|
||||||
expect(body.data.id).toEqual(group.id);
|
expect(body.data.id).toEqual(group.id);
|
||||||
});
|
});
|
||||||
|
|
||||||
it("should not return group if non-member, non-admin", async () => {
|
it("should still return group if non-member, non-admin", async () => {
|
||||||
const user = await buildUser();
|
const user = await buildUser();
|
||||||
const group = await buildGroup({ teamId: user.teamId });
|
const group = await buildGroup({ teamId: user.teamId });
|
||||||
|
|
||||||
|
@ -211,7 +211,10 @@ describe("#groups.info", () => {
|
||||||
body: { token: user.getJwtToken(), id: group.id },
|
body: { token: user.getJwtToken(), id: group.id },
|
||||||
});
|
});
|
||||||
|
|
||||||
expect(res.status).toEqual(403);
|
const body = await res.json();
|
||||||
|
|
||||||
|
expect(res.status).toEqual(200);
|
||||||
|
expect(body.data.id).toEqual(group.id);
|
||||||
});
|
});
|
||||||
|
|
||||||
it("should require authentication", async () => {
|
it("should require authentication", async () => {
|
||||||
|
|
Reference in New Issue