mirror of
https://github.com/outline/outline.git
synced 2026-06-13 11:25:03 +03:00
Fetch subscription data using 'subscriptions.info' API (#8368)
* Fetch subscription data using 'subscriptions.info' API * use getByDocumentId * throw 404 * unnecessary notfound error
This commit is contained in:
@@ -358,7 +358,7 @@ export const unsubscribeDocument = createAction({
|
||||
|
||||
const document = stores.documents.get(activeDocumentId);
|
||||
|
||||
await document?.unsubscribe(currentUserId);
|
||||
await document?.unsubscribe();
|
||||
|
||||
toast.success(t("Unsubscribed from document notifications"));
|
||||
},
|
||||
|
||||
@@ -96,7 +96,7 @@ const MenuTrigger: React.FC<MenuTriggerProps> = ({ label, onTrigger }) => {
|
||||
const { model: document, menuState } = useMenuContext<Document>();
|
||||
|
||||
const { data, loading, error, request } = useRequest(() =>
|
||||
subscriptions.fetchPage({
|
||||
subscriptions.fetchOne({
|
||||
documentId: document.id,
|
||||
event: "documents.update",
|
||||
})
|
||||
|
||||
@@ -307,9 +307,7 @@ export default class Document extends ArchivableModel implements Searchable {
|
||||
*/
|
||||
@computed
|
||||
get isSubscribed(): boolean {
|
||||
return !!this.store.rootStore.subscriptions.orderedData.find(
|
||||
(subscription) => subscription.documentId === this.id
|
||||
);
|
||||
return !!this.store.rootStore.subscriptions.getByDocumentId(this.id);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -501,7 +499,7 @@ export default class Document extends ArchivableModel implements Searchable {
|
||||
* @returns A promise that resolves when the subscription is destroyed.
|
||||
*/
|
||||
@action
|
||||
unsubscribe = (userId: string) => this.store.unsubscribe(userId, this);
|
||||
unsubscribe = () => this.store.unsubscribe(this);
|
||||
|
||||
@action
|
||||
view = () => {
|
||||
|
||||
@@ -816,9 +816,9 @@ export default class DocumentsStore extends Store<Document> {
|
||||
event: "documents.update",
|
||||
});
|
||||
|
||||
unsubscribe = (userId: string, document: Document) => {
|
||||
const subscription = this.rootStore.subscriptions.orderedData.find(
|
||||
(s) => s.documentId === document.id && s.userId === userId
|
||||
unsubscribe = (document: Document) => {
|
||||
const subscription = this.rootStore.subscriptions.getByDocumentId(
|
||||
document.id
|
||||
);
|
||||
|
||||
return subscription?.delete();
|
||||
|
||||
@@ -1,4 +1,8 @@
|
||||
import invariant from "invariant";
|
||||
import { action } from "mobx";
|
||||
import Subscription from "~/models/Subscription";
|
||||
import { client } from "~/utils/ApiClient";
|
||||
import { AuthorizationError, NotFoundError } from "~/utils/errors";
|
||||
import RootStore from "./RootStore";
|
||||
import Store, { RPCAction } from "./base/Store";
|
||||
|
||||
@@ -8,4 +12,34 @@ export default class SubscriptionsStore extends Store<Subscription> {
|
||||
constructor(rootStore: RootStore) {
|
||||
super(rootStore, Subscription);
|
||||
}
|
||||
|
||||
@action
|
||||
async fetchOne({ documentId, event }: { documentId: string; event: string }) {
|
||||
const subscription = this.getByDocumentId(documentId);
|
||||
|
||||
if (subscription) {
|
||||
return subscription;
|
||||
}
|
||||
|
||||
this.isFetching = true;
|
||||
|
||||
try {
|
||||
const res = await client.post(`/${this.apiEndpoint}.info`, {
|
||||
documentId,
|
||||
event,
|
||||
});
|
||||
invariant(res?.data, "Data should be available");
|
||||
return this.add(res.data);
|
||||
} catch (err) {
|
||||
if (err instanceof AuthorizationError || err instanceof NotFoundError) {
|
||||
return;
|
||||
}
|
||||
throw err;
|
||||
} finally {
|
||||
this.isFetching = false;
|
||||
}
|
||||
}
|
||||
|
||||
getByDocumentId = (documentId: string): Subscription | undefined =>
|
||||
this.find({ documentId });
|
||||
}
|
||||
|
||||
@@ -202,6 +202,25 @@ describe("#subscriptions.info", () => {
|
||||
expect(response0.data.documentId).toEqual(document0.id);
|
||||
});
|
||||
|
||||
it("should throw 404 if no subscription found", async () => {
|
||||
const author = await buildUser();
|
||||
const subscriber = await buildUser({ teamId: author.teamId });
|
||||
const document = await buildDocument({
|
||||
userId: author.id,
|
||||
teamId: author.teamId,
|
||||
});
|
||||
|
||||
const res = await server.post("/api/subscriptions.info", {
|
||||
body: {
|
||||
token: subscriber.getJwtToken(),
|
||||
documentId: document.id,
|
||||
event: "documents.update",
|
||||
},
|
||||
});
|
||||
|
||||
expect(res.status).toEqual(404);
|
||||
});
|
||||
|
||||
it("should not allow outsiders to gain info about a subscription", async () => {
|
||||
const creator = await buildUser();
|
||||
const subscriber = await buildUser({ teamId: creator.teamId });
|
||||
|
||||
Reference in New Issue
Block a user