1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
|
/*
Spacebar: A FOSS re-implementation and extension of the Discord.com backend.
Copyright (C) 2023 Fosscord and Fosscord Contributors
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as published
by the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Affero General Public License for more details.
You should have received a copy of the GNU Affero General Public License
along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
import { BitField } from "./BitField";
import "missing-native-js-functions";
import { BitFieldResolvable, BitFlag } from "./BitField";
import { User } from "../entities";
import { HTTPError } from "lambert-server";
export type RightResolvable =
| bigint
| number
| Rights
| RightResolvable[]
| RightString;
type RightString = keyof typeof Rights.FLAGS;
// TODO: just like roles for members, users should have privilidges which combine multiple rights into one and make it easy to assign
export class Rights extends BitField {
constructor(bits: BitFieldResolvable = 0) {
super(bits);
if (this.bitfield & Rights.FLAGS.OPERATOR) {
this.bitfield = ALL_RIGHTS;
}
}
static FLAGS = {
OPERATOR: BitFlag(0), // has all rights
MANAGE_APPLICATIONS: BitFlag(1),
MANAGE_GUILDS: BitFlag(2), // Manage all guilds instance-wide
MANAGE_MESSAGES: BitFlag(3), // Can't see other messages but delete/edit them in channels that they can see
MANAGE_RATE_LIMITS: BitFlag(4),
MANAGE_ROUTING: BitFlag(5), // can create custom message routes to any channel/guild
MANAGE_TICKETS: BitFlag(6), // can respond to and resolve support tickets
MANAGE_USERS: BitFlag(7),
ADD_MEMBERS: BitFlag(8), // can manually add any members in their guilds
BYPASS_RATE_LIMITS: BitFlag(9),
CREATE_APPLICATIONS: BitFlag(10),
CREATE_CHANNELS: BitFlag(11), // can create guild channels or threads in the guilds that they have permission
CREATE_DMS: BitFlag(12),
CREATE_DM_GROUPS: BitFlag(13), // can create group DMs or custom orphan channels
CREATE_GUILDS: BitFlag(14),
CREATE_INVITES: BitFlag(15), // can create mass invites in the guilds that they have CREATE_INSTANT_INVITE
CREATE_ROLES: BitFlag(16),
CREATE_TEMPLATES: BitFlag(17),
CREATE_WEBHOOKS: BitFlag(18),
JOIN_GUILDS: BitFlag(19),
PIN_MESSAGES: BitFlag(20),
SELF_ADD_REACTIONS: BitFlag(21),
SELF_DELETE_MESSAGES: BitFlag(22),
SELF_EDIT_MESSAGES: BitFlag(23),
SELF_EDIT_NAME: BitFlag(24),
SEND_MESSAGES: BitFlag(25),
USE_ACTIVITIES: BitFlag(26), // use (game) activities in voice channels (e.g. Watch together)
USE_VIDEO: BitFlag(27),
USE_VOICE: BitFlag(28),
INVITE_USERS: BitFlag(29), // can create user-specific invites in the guilds that they have INVITE_USERS
SELF_DELETE_DISABLE: BitFlag(30), // can disable/delete own account
DEBTABLE: BitFlag(31), // can use pay-to-use features
CREDITABLE: BitFlag(32), // can receive money from monetisation related features
KICK_BAN_MEMBERS: BitFlag(33),
// can kick or ban guild or group DM members in the guilds/groups that they have KICK_MEMBERS, or BAN_MEMBERS
SELF_LEAVE_GROUPS: BitFlag(34),
// can leave the guilds or group DMs that they joined on their own (one can always leave a guild or group DMs they have been force-added)
PRESENCE: BitFlag(35),
// inverts the presence confidentiality default (OPERATOR's presence is not routed by default, others' are) for a given user
SELF_ADD_DISCOVERABLE: BitFlag(36), // can mark discoverable guilds that they have permissions to mark as discoverable
MANAGE_GUILD_DIRECTORY: BitFlag(37), // can change anything in the primary guild directory
POGGERS: BitFlag(38), // can send confetti, screenshake, random user mention (@someone)
USE_ACHIEVEMENTS: BitFlag(39), // can use achievements and cheers
INITIATE_INTERACTIONS: BitFlag(40), // can initiate interactions
RESPOND_TO_INTERACTIONS: BitFlag(41), // can respond to interactions
SEND_BACKDATED_EVENTS: BitFlag(42), // can send backdated events
USE_MASS_INVITES: BitFlag(43), // added per @xnacly's request — can accept mass invites
ACCEPT_INVITES: BitFlag(44), // added per @xnacly's request — can accept user-specific invites and DM requests
SELF_EDIT_FLAGS: BitFlag(45), // can modify own flags
EDIT_FLAGS: BitFlag(46), // can set others' flags
MANAGE_GROUPS: BitFlag(47), // can manage others' groups
VIEW_SERVER_STATS: BitFlag(48), // added per @chrischrome's request — can view server stats)
RESEND_VERIFICATION_EMAIL: BitFlag(49), // can resend verification emails (/auth/verify/resend)
};
any(permission: RightResolvable, checkOperator = true) {
return (
(checkOperator && super.any(Rights.FLAGS.OPERATOR)) ||
super.any(permission)
);
}
has(permission: RightResolvable, checkOperator = true) {
return (
(checkOperator && super.has(Rights.FLAGS.OPERATOR)) ||
super.has(permission)
);
}
hasThrow(permission: RightResolvable) {
if (this.has(permission)) return true;
throw new HTTPError(
`You are missing the following rights ${permission}`,
403,
);
}
}
const ALL_RIGHTS = Object.values(Rights.FLAGS).reduce(
(total, val) => total | val,
BigInt(0),
);
export async function getRights(
user_id: string,
/**, opts: {
in_behalf?: (keyof User)[];
} = {} **/
) {
const user = await User.findOneOrFail({ where: { id: user_id } });
return new Rights(user.rights);
}
|