Skip to content

Commit

Permalink
feat(discussions): add checks if user is allowed to access it
Browse files Browse the repository at this point in the history
  • Loading branch information
Vexcited committed Apr 28, 2024
1 parent 18956d0 commit b00a90a
Show file tree
Hide file tree
Showing 4 changed files with 44 additions and 15 deletions.
4 changes: 2 additions & 2 deletions src/api/user/data/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -212,10 +212,10 @@ export interface PronoteApiUserData {

/** Authorization for the current student. */
autorisations: {
/** Is allowed to create discussions ? */
/** Whether the user is allowed to read discussions or messages. */
AvecDiscussion?: boolean

/** Whether the user is disallowed to read/create discussions. */
/** Whether the user is disallowed to create discussions or messages. */
discussionInterdit?: boolean

/**
Expand Down
32 changes: 24 additions & 8 deletions src/client/Pronote.ts
Original file line number Diff line number Diff line change
Expand Up @@ -479,15 +479,27 @@ export default class Pronote {
});
}

#throwIfNotAllowedReadMessages (): void {
if (!this.authorizations.canReadDiscussions) throw new Error("You can't read messages in this instance.");
}

#throwIfNotAllowedCreateMessages (): void {
if (!this.authorizations.canDiscuss) throw new Error("You can't create messages in this instance.");
}

public async getDiscussionsOverview (): Promise<StudentDiscussionsOverview> {
return this.queue.push(async () => {
this.#throwIfNotAllowedReadMessages();

const { data } = await callApiUserDiscussions(this.fetcher, { session: this.session });
return new StudentDiscussionsOverview(this, this.queue, this.session, data.donnees);
});
}

public async getMessagesOverviewFromDiscussion (discussion: StudentDiscussion, markAsRead = false, limit = 0): Promise<MessagesOverview> {
return this.queue.push(async () => {
this.#throwIfNotAllowedReadMessages();

const { data } = await callApiUserMessages(this.fetcher, { possessions: discussion.possessions, session: this.session, markAsRead, limit });
return new MessagesOverview(
this, this.queue, this.session,
Expand All @@ -499,6 +511,8 @@ export default class Pronote {

public async postDiscussionCommand (payload: ApiUserDiscussionAvailableCommands): Promise<void> {
await this.queue.push(async () => {
this.#throwIfNotAllowedCreateMessages();

await callApiUserDiscussionCommand(this.fetcher, {
session: this.session,
...payload
Expand All @@ -516,6 +530,8 @@ export default class Pronote {

public async getRecipientsForMessage (messageID: string): Promise<FetchedMessageRecipient[]> {
return this.queue.push(async () => {
this.#throwIfNotAllowedReadMessages();

const { data } = await callApiUserMessageRecipients(this.fetcher, {
session: this.session,
messageID
Expand Down Expand Up @@ -612,8 +628,6 @@ export default class Pronote {
}

#throwIfNotAllowedRecipientType (type: PronoteApiUserResourceType): void {
if (!this.authorizations.canDiscuss) throw new Error("You don't have access to discussion.");

switch (type) {
case PronoteApiResourceType.Teacher:
if (!this.authorizations.canDiscussWithTeachers)
Expand All @@ -637,9 +651,9 @@ export default class Pronote {
* It allows to know who can be the recipient of the discussion.
*/
public async getRecipientsForDiscussionCreation (type: PronoteApiUserResourceType): Promise<DiscussionCreationRecipient[]> {
this.#throwIfNotAllowedRecipientType(type);

return this.queue.push(async () => {
this.#throwIfNotAllowedRecipientType(type);

const response = await callApiUserCreateDiscussionRecipients(this.fetcher, {
recipientType: type,
session: this.session,
Expand All @@ -664,9 +678,10 @@ export default class Pronote {
* discussions list once again using `getDiscussionsOverview()`.
*/
public async createDiscussion (subject: string, content: string, recipients: DiscussionCreationRecipient[]): Promise<void> {
if (recipients.length <= 0) throw new Error("You need to select at least one recipient to create a discussion.");

return this.queue.push(async () => {
this.#throwIfNotAllowedCreateMessages();
if (recipients.length <= 0) throw new Error("You need to select at least one recipient to create a discussion.");

await callApiUserCreateDiscussion(this.fetcher, {
session: this.session,
recipients,
Expand All @@ -680,9 +695,10 @@ export default class Pronote {
}

public async replyToDiscussionMessage (replyMessageID: string, content: string, button: PronoteApiMessagesButtonType, includeParentsAndStudents = false): Promise<void> {
const buttonType = getPronoteMessageButtonType(button, includeParentsAndStudents);

return this.queue.push(async () => {
this.#throwIfNotAllowedCreateMessages();
const buttonType = getPronoteMessageButtonType(button, includeParentsAndStudents);

await callApiUserCreateDiscussionMessage(this.fetcher, {
session: this.session,
replyMessageID,
Expand Down
13 changes: 11 additions & 2 deletions src/parser/authorizations.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import type { ApiUserData } from "~/api";

class Authorizations {
readonly #canReadDiscussions: boolean;
readonly #canDiscuss: boolean;

readonly #canDiscussWithStaff: boolean;
Expand All @@ -13,7 +14,8 @@ class Authorizations {
readonly #maxHomeworkFileUploadSize: number;

constructor (data: ApiUserData["output"]["data"]["donnees"]["autorisations"]) {
this.#canDiscuss = (data.AvecDiscussion ?? false) && !(data.discussionInterdit ?? false);
this.#canReadDiscussions = data.AvecDiscussion ?? false;
this.#canDiscuss = this.#canReadDiscussions && !(data.discussionInterdit ?? false);

this.#canDiscussWithStaff = this.#canDiscuss && (data.AvecDiscussionPersonnels ?? false);
this.#canDiscussWithParents = this.#canDiscuss && (data.AvecDiscussionParents ?? false);
Expand All @@ -26,7 +28,14 @@ class Authorizations {
}

/**
* Whether the user is allowed to discuss.
* Whether the user is allowed to read discussions.
*/
public get canReadDiscussions (): boolean {
return this.#canReadDiscussions;
}

/**
* Whether the user is allowed to create messages in discussions.
*/
public get canDiscuss (): boolean {
return this.#canDiscuss;
Expand Down
10 changes: 7 additions & 3 deletions src/parser/messages.ts
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ export class MessagesOverview {
#messages: SentMessage[] = [];
#savedDrafts: DraftMessage[] = [];
// Needed to create a new message...
#sendButtonGenre: PronoteApiMessagesButtonType;
#sendButtonGenre?: PronoteApiMessagesButtonType;
#fetchLimit: number;

public async refetch (limit = this.#fetchLimit) {
Expand Down Expand Up @@ -53,8 +53,9 @@ export class MessagesOverview {
this.#fetchLimit = limit;
}

#readSendButton (listeBoutons: PronoteApiUserMessages["response"]["donnees"]["listeBoutons"]["V"]): PronoteApiMessagesButtonType {
return listeBoutons.find((button) => button.L.startsWith("Envoyer"))!.G;
#readSendButton (listeBoutons: PronoteApiUserMessages["response"]["donnees"]["listeBoutons"]["V"]): PronoteApiMessagesButtonType | undefined {
const button = listeBoutons.find((button) => button.L.startsWith("Envoyer"));
return button?.G;
}

#parseMessages (listeMessages: PronoteApiUserMessages["response"]["donnees"]["listeMessages"]["V"]): void {
Expand Down Expand Up @@ -146,6 +147,8 @@ export class MessagesOverview {
* internally so properties are automatically updated.
*/
public async sendMessage (content: string, includeParentsAndStudents = false, replyTo = this.#defaultReplyMessageID): Promise<void> {
if (typeof this.#sendButtonGenre === "undefined") throw new Error("You can't create messages in this discussion.");

await this.#client.replyToDiscussionMessage(replyTo, content, this.#sendButtonGenre, includeParentsAndStudents);
await this.refetch();
}
Expand Down Expand Up @@ -182,6 +185,7 @@ export class MessagesOverview {
}

public async sendDraft (draft: DraftMessage, includeParentsAndStudents = false): Promise<void> {
if (typeof this.#sendButtonGenre === "undefined") throw new Error("You can't create drafts in this discussion.");
const buttonType = getPronoteMessageButtonType(this.#sendButtonGenre, includeParentsAndStudents);

await this.#client.postDiscussionCommand({
Expand Down

0 comments on commit b00a90a

Please sign in to comment.