{ "version": 3, "sources": ["../../../server/user-groups.ts"], "sourcesContent": ["import {FS} from '../lib/fs';\r\nimport type {RoomSection} from './chat-commands/room-settings';\r\n\r\nexport type GroupSymbol = '~' | '&' | '#' | '\u2605' | '*' | '@' | '%' | '\u2606' | '\u00A7' | '+' | '^' | ' ' | '\u203D' | '!';\r\nexport type EffectiveGroupSymbol = GroupSymbol | 'whitelist';\r\nexport type AuthLevel = EffectiveGroupSymbol | 'unlocked' | 'trusted' | 'autoconfirmed';\r\n\r\nexport const SECTIONLEADER_SYMBOL: GroupSymbol = '\\u00a7';\r\nexport const PLAYER_SYMBOL: GroupSymbol = '\\u2606';\r\nexport const HOST_SYMBOL: GroupSymbol = '\\u2605';\r\n\r\nexport const ROOM_PERMISSIONS = [\r\n\t'addhtml', 'announce', 'ban', 'bypassafktimer', 'declare', 'editprivacy', 'editroom', 'exportinputlog', 'game', 'gamemanagement', 'gamemoderation', 'joinbattle', 'kick', 'minigame', 'modchat', 'modlog', 'mute', 'nooverride', 'receiveauthmessages', 'roombot', 'roomdriver', 'roommod', 'roomowner', 'roomsectionleader', 'roomvoice', 'roomprizewinner', 'show', 'showmedia', 'timer', 'tournaments', 'warn',\r\n] as const;\r\n\r\nexport const GLOBAL_PERMISSIONS = [\r\n\t// administrative\r\n\t'bypassall', 'console', 'disableladder', 'lockdown', 'potd',\r\n\t// other\r\n\t'addhtml', 'alts', 'altsself', 'autotimer', 'globalban', 'bypassblocks', 'bypassafktimer', 'forcepromote', 'forcerename', 'forcewin', 'gdeclare', 'hiderank', 'ignorelimits', 'importinputlog', 'ip', 'ipself', 'lock', 'makeroom', 'modlog', 'rangeban', 'promote',\r\n] as const;\r\n\r\nexport type RoomPermission = typeof ROOM_PERMISSIONS[number];\r\nexport type GlobalPermission = typeof GLOBAL_PERMISSIONS[number];\r\n\r\nexport type GroupInfo = {\r\n\tsymbol: GroupSymbol,\r\n\tid: ID,\r\n\tname: string,\r\n\trank: number,\r\n\tinherit?: GroupSymbol,\r\n\tjurisdiction?: string,\r\n\r\n\tglobalonly?: boolean,\r\n\troomonly?: boolean,\r\n\tbattleonly?: boolean,\r\n\troot?: boolean,\r\n\tglobalGroupInPersonalRoom?: GroupSymbol,\r\n} & {\r\n\t[P in RoomPermission | GlobalPermission]?: string | boolean;\r\n};\r\n\r\n/**\r\n * Auth table - a Map for which users are in which groups.\r\n *\r\n * Notice that auth.get will return the default group symbol if the\r\n * user isn't in a group.\r\n */\r\nexport abstract class Auth extends Map {\r\n\t/**\r\n\t * Will return the default group symbol if the user isn't in a group.\r\n\t *\r\n\t * Passing a User will read `user.group`, which is relevant for unregistered\r\n\t * users with temporary global auth.\r\n\t */\r\n\tget(user: ID | User) {\r\n\t\tif (typeof user !== 'string') return user.tempGroup;\r\n\t\treturn super.get(user) || Auth.defaultSymbol();\r\n\t}\r\n\tisStaff(userid: ID) {\r\n\t\tif (this.has(userid)) {\r\n\t\t\tconst rank = this.get(userid);\r\n\t\t\t// At one point bots used to be ranked above drivers, so this checks\r\n\t\t\t// driver rank to make sure this function works on servers that\r\n\t\t\t// did not reorder the ranks.\r\n\t\t\treturn Auth.atLeast(rank, '*') || Auth.atLeast(rank, SECTIONLEADER_SYMBOL) || Auth.atLeast(rank, '%');\r\n\t\t} else {\r\n\t\t\treturn false;\r\n\t\t}\r\n\t}\r\n\tatLeast(user: User, group: AuthLevel) {\r\n\t\tif (user.hasSysopAccess()) return true;\r\n\t\tif (group === 'trusted' || group === 'autoconfirmed') {\r\n\t\t\tif (user.trusted && group === 'trusted') return true;\r\n\t\t\tif (user.autoconfirmed && !user.locked && group === 'autoconfirmed') return true;\r\n\t\t\tgroup = Config.groupsranking[1];\r\n\t\t}\r\n\t\tif (user.locked || user.semilocked) return false;\r\n\t\tif (group === 'unlocked') return true;\r\n\t\tif (group === 'whitelist' && this.has(user.id)) {\r\n\t\t\treturn true;\r\n\t\t}\r\n\t\tif (!Config.groups[group]) return false;\r\n\t\tif (this.get(user.id) === ' ' && group !== ' ') return false;\r\n\t\treturn Auth.atLeast(this.get(user.id), group);\r\n\t}\r\n\r\n\tstatic defaultSymbol() {\r\n\t\treturn Config.groupsranking[0] as GroupSymbol;\r\n\t}\r\n\tstatic getGroup(symbol: EffectiveGroupSymbol): GroupInfo;\r\n\tstatic getGroup(symbol: EffectiveGroupSymbol, fallback: T): GroupInfo | T;\r\n\tstatic getGroup(symbol: EffectiveGroupSymbol, fallback?: AnyObject) {\r\n\t\tif (Config.groups[symbol]) return Config.groups[symbol];\r\n\r\n\t\tif (fallback !== undefined) return fallback;\r\n\r\n\t\t// unidentified groups are treated as voice\r\n\t\treturn {\r\n\t\t\t...(Config.groups['+'] || {}),\r\n\t\t\tsymbol,\r\n\t\t\tid: 'voice',\r\n\t\t\tname: symbol,\r\n\t\t};\r\n\t}\r\n\tgetEffectiveSymbol(user: User): EffectiveGroupSymbol {\r\n\t\tconst group = this.get(user);\r\n\t\tif (this.has(user.id) && group === Auth.defaultSymbol()) {\r\n\t\t\treturn 'whitelist';\r\n\t\t}\r\n\t\treturn group;\r\n\t}\r\n\tstatic hasPermission(\r\n\t\tuser: User,\r\n\t\tpermission: string,\r\n\t\ttarget: User | EffectiveGroupSymbol | ID | null,\r\n\t\troom?: BasicRoom | null,\r\n\t\tcmd?: string\r\n\t): boolean {\r\n\t\tif (user.hasSysopAccess()) return true;\r\n\r\n\t\tconst auth: Auth = room ? room.auth : Users.globalAuth;\r\n\r\n\t\tconst symbol = auth.getEffectiveSymbol(user);\r\n\r\n\t\tlet targetSymbol: EffectiveGroupSymbol | null;\r\n\t\tif (!target) {\r\n\t\t\ttargetSymbol = null;\r\n\t\t} else if (typeof target === 'string' && !toID(target)) { // empty ID -> target is a group symbol\r\n\t\t\ttargetSymbol = target as EffectiveGroupSymbol;\r\n\t\t} else {\r\n\t\t\ttargetSymbol = auth.get(target as User | ID);\r\n\t\t}\r\n\t\tif (!targetSymbol || ['whitelist', 'trusted', 'autoconfirmed'].includes(targetSymbol)) {\r\n\t\t\ttargetSymbol = Auth.defaultSymbol();\r\n\t\t}\r\n\r\n\t\tlet group = Auth.getGroup(symbol);\r\n\t\tif (group['root']) return true;\r\n\t\tif (\r\n\t\t\troom?.settings.section &&\r\n\t\t\troom.settings.section === Users.globalAuth.sectionLeaders.get(user.id) &&\r\n\t\t\t// Global drivers who are SLs should get room mod powers too\r\n\t\t\tUsers.globalAuth.atLeast(user, SECTIONLEADER_SYMBOL) &&\r\n\t\t\t// But dont override ranks above moderator such as room owner\r\n\t\t\t(Auth.getGroup('@').rank > group.rank)\r\n\t\t) {\r\n\t\t\tgroup = Auth.getGroup('@');\r\n\t\t}\r\n\r\n\t\tlet jurisdiction = group[permission as GlobalPermission | RoomPermission];\r\n\t\tif (jurisdiction === true && permission !== 'jurisdiction') {\r\n\t\t\tjurisdiction = group['jurisdiction'] || true;\r\n\t\t}\r\n\t\tconst roomPermissions = room ? room.settings.permissions : null;\r\n\t\tif (roomPermissions) {\r\n\t\t\tlet foundSpecificPermission = false;\r\n\t\t\tif (cmd) {\r\n\t\t\t\tconst namespace = cmd.slice(0, cmd.indexOf(' '));\r\n\t\t\t\tif (roomPermissions[`/${cmd}`]) {\r\n\t\t\t\t\t// this checks sub commands and command objects, but it checks to see if a sub-command\r\n\t\t\t\t\t// overrides (should a perm for the command object exist) first\r\n\t\t\t\t\tif (!auth.atLeast(user, roomPermissions[`/${cmd}`])) return false;\r\n\t\t\t\t\tjurisdiction = 'u';\r\n\t\t\t\t\tfoundSpecificPermission = true;\r\n\t\t\t\t} else if (roomPermissions[`/${namespace}`]) {\r\n\t\t\t\t\t// if it's for one command object\r\n\t\t\t\t\tif (!auth.atLeast(user, roomPermissions[`/${namespace}`])) return false;\r\n\t\t\t\t\tjurisdiction = 'u';\r\n\t\t\t\t\tfoundSpecificPermission = true;\r\n\t\t\t\t}\r\n\t\t\t}\r\n\t\t\tif (!foundSpecificPermission && roomPermissions[permission]) {\r\n\t\t\t\tif (!auth.atLeast(user, roomPermissions[permission])) return false;\r\n\t\t\t\tjurisdiction = 'u';\r\n\t\t\t}\r\n\t\t}\r\n\t\treturn Auth.hasJurisdiction(symbol, jurisdiction, targetSymbol as GroupSymbol);\r\n\t}\r\n\tstatic atLeast(symbol: EffectiveGroupSymbol, symbol2: EffectiveGroupSymbol) {\r\n\t\treturn Auth.getGroup(symbol).rank >= Auth.getGroup(symbol2).rank;\r\n\t}\r\n\tstatic supportedRoomPermissions(room: Room | null = null) {\r\n\t\tconst handlers = Chat.allCommands().filter(c => c.hasRoomPermissions);\r\n\t\tconst commands = [];\r\n\t\tfor (const handler of handlers) {\r\n\t\t\tcommands.push(`/${handler.fullCmd}`);\r\n\t\t\tif (handler.aliases.length) {\r\n\t\t\t\tfor (const alias of handler.aliases) {\r\n\t\t\t\t\t// kind of a hack but this is the only good way i could think of to\r\n\t\t\t\t\t// overwrite the alias without making assumptions about the string\r\n\t\t\t\t\tcommands.push(`/${handler.fullCmd.replace(handler.cmd, alias)}`);\r\n\t\t\t\t}\r\n\t\t\t}\r\n\t\t}\r\n\t\treturn [\r\n\t\t\t...ROOM_PERMISSIONS,\r\n\t\t\t...commands,\r\n\t\t];\r\n\t}\r\n\tstatic hasJurisdiction(\r\n\t\tsymbol: EffectiveGroupSymbol,\r\n\t\tjurisdiction?: string | boolean,\r\n\t\ttargetSymbol?: GroupSymbol | null\r\n\t) {\r\n\t\tif (!targetSymbol) {\r\n\t\t\treturn !!jurisdiction;\r\n\t\t}\r\n\t\tif (typeof jurisdiction !== 'string') {\r\n\t\t\treturn !!jurisdiction;\r\n\t\t}\r\n\t\tif (jurisdiction.includes(targetSymbol)) {\r\n\t\t\treturn true;\r\n\t\t}\r\n\t\tif (jurisdiction.includes('a')) {\r\n\t\t\treturn true;\r\n\t\t}\r\n\t\tif (jurisdiction.includes('u') && Auth.getGroup(symbol).rank > Auth.getGroup(targetSymbol).rank) {\r\n\t\t\treturn true;\r\n\t\t}\r\n\t\treturn false;\r\n\t}\r\n\tstatic listJurisdiction(user: User, permission: GlobalPermission | RoomPermission) {\r\n\t\tconst symbols = Object.keys(Config.groups) as GroupSymbol[];\r\n\t\treturn symbols.filter(targetSymbol => Auth.hasPermission(user, permission, targetSymbol));\r\n\t}\r\n\tstatic isValidSymbol(symbol: string): symbol is GroupSymbol {\r\n\t\tif (symbol.length !== 1) return false;\r\n\t\treturn !/[A-Za-z0-9|,]/.test(symbol);\r\n\t}\r\n\tstatic isAuthLevel(level: string): level is AuthLevel {\r\n\t\tif (Config.groupsranking.includes(level as EffectiveGroupSymbol)) return true;\r\n\t\treturn ['\u203D', '!', 'unlocked', 'trusted', 'autoconfirmed', 'whitelist'].includes(level);\r\n\t}\r\n\tstatic ROOM_PERMISSIONS = ROOM_PERMISSIONS;\r\n\tstatic GLOBAL_PERMISSIONS = GLOBAL_PERMISSIONS;\r\n}\r\n\r\nexport class RoomAuth extends Auth {\r\n\troom: BasicRoom;\r\n\tconstructor(room: BasicRoom) {\r\n\t\tsuper();\r\n\t\tthis.room = room;\r\n\t}\r\n\tget(userOrID: ID | User): GroupSymbol {\r\n\t\tconst id = typeof userOrID === 'string' ? userOrID : userOrID.id;\r\n\r\n\t\tconst parentAuth: Auth | null = this.room.parent ? this.room.parent.auth :\r\n\t\t\tthis.room.settings.isPrivate !== true ? Users.globalAuth : null;\r\n\t\tconst parentGroup = parentAuth ? parentAuth.get(userOrID) : Auth.defaultSymbol();\r\n\r\n\t\tif (this.has(id)) {\r\n\t\t\t// authority is whichever is higher between roomauth and global auth\r\n\t\t\tconst roomGroup = this.getDirect(id);\r\n\t\t\tlet group = Config.greatergroupscache[`${roomGroup}${parentGroup}`];\r\n\t\t\tif (!group) {\r\n\t\t\t\t// unrecognized groups always trump higher global rank\r\n\t\t\t\tconst roomRank = Auth.getGroup(roomGroup, {rank: Infinity}).rank;\r\n\t\t\t\tconst globalRank = Auth.getGroup(parentGroup).rank;\r\n\t\t\t\tif (roomGroup === Users.PLAYER_SYMBOL || roomGroup === Users.HOST_SYMBOL || roomGroup === '#') {\r\n\t\t\t\t\t// Player, Host, and Room Owner always trump higher global rank\r\n\t\t\t\t\tgroup = roomGroup;\r\n\t\t\t\t} else {\r\n\t\t\t\t\tgroup = (roomRank > globalRank ? roomGroup : parentGroup);\r\n\t\t\t\t}\r\n\t\t\t\tConfig.greatergroupscache[`${roomGroup}${parentGroup}`] = group;\r\n\t\t\t}\r\n\t\t\treturn group;\r\n\t\t}\r\n\r\n\t\treturn parentGroup;\r\n\t}\r\n\tgetEffectiveSymbol(user: User) {\r\n\t\tconst symbol = super.getEffectiveSymbol(user);\r\n\t\tif (!this.room.persist && symbol === user.tempGroup) {\r\n\t\t\tconst replaceGroup = Auth.getGroup(symbol).globalGroupInPersonalRoom;\r\n\t\t\tif (replaceGroup) return replaceGroup;\r\n\t\t}\r\n\t\t// this is a bit of a hardcode, yeah, but admins need to have admin commands in prooms w/o the symbol\r\n\t\t// and we want that to include sysops.\r\n\t\t// Plus, using user.can is cleaner than Users.globalAuth.get(user) === admin and it accounts for more things.\r\n\t\t// (and no this won't recurse or anything since user.can() with no room doesn't call this)\r\n\t\tif (this.room.settings.isPrivate === true && user.can('makeroom')) {\r\n\t\t\t// not hardcoding & here since globalAuth.get should return & in basically all cases\r\n\t\t\t// except sysops, and there's an override for them anyways so it doesn't matter\r\n\t\t\treturn Users.globalAuth.get(user);\r\n\t\t}\r\n\t\treturn symbol;\r\n\t}\r\n\t/** gets the room group without inheriting */\r\n\tgetDirect(id: ID): GroupSymbol {\r\n\t\treturn super.get(id);\r\n\t}\r\n\tsave() {\r\n\t\t// construct auth object\r\n\t\tconst auth = Object.create(null);\r\n\t\tfor (const [userid, groupSymbol] of this) {\r\n\t\t\tauth[userid] = groupSymbol;\r\n\t\t}\r\n\t\t(this.room.settings as any).auth = auth;\r\n\t\tthis.room.saveSettings();\r\n\t}\r\n\tload() {\r\n\t\tfor (const userid in this.room.settings.auth) {\r\n\t\t\tsuper.set(userid as ID, this.room.settings.auth[userid]);\r\n\t\t}\r\n\t}\r\n\tset(id: ID, symbol: GroupSymbol) {\r\n\t\tif (symbol === 'whitelist' as GroupSymbol) {\r\n\t\t\tsymbol = Auth.defaultSymbol();\r\n\t\t}\r\n\t\tsuper.set(id, symbol);\r\n\t\tthis.room.settings.auth[id] = symbol;\r\n\t\tthis.room.saveSettings();\r\n\r\n\t\tconst user = Users.get(id);\r\n\t\tif (user) this.room.onUpdateIdentity(user);\r\n\t\treturn this;\r\n\t}\r\n\tdelete(id: ID) {\r\n\t\tif (!this.has(id)) return false;\r\n\t\tsuper.delete(id);\r\n\t\tdelete this.room.settings.auth[id];\r\n\t\tthis.room.saveSettings();\r\n\t\treturn true;\r\n\t}\r\n}\r\n\r\nexport class GlobalAuth extends Auth {\r\n\tusernames = new Map();\r\n\tsectionLeaders = new Map();\r\n\tconstructor() {\r\n\t\tsuper();\r\n\t\tthis.load();\r\n\t}\r\n\tsave() {\r\n\t\tFS('config/usergroups.csv').writeUpdate(() => {\r\n\t\t\tlet buffer = '';\r\n\t\t\tfor (const [userid, groupSymbol] of this) {\r\n\t\t\t\tbuffer += `${this.usernames.get(userid) || userid},${groupSymbol},${this.sectionLeaders.get(userid) || ''}\\n`;\r\n\t\t\t}\r\n\t\t\treturn buffer;\r\n\t\t});\r\n\t}\r\n\tload() {\r\n\t\tconst data = FS('config/usergroups.csv').readIfExistsSync();\r\n\t\tfor (const row of data.split(\"\\n\")) {\r\n\t\t\tif (!row) continue;\r\n\t\t\tconst [name, symbol, sectionid] = row.split(\",\");\r\n\t\t\tconst id = toID(name);\r\n\t\t\tif (!id) {\r\n\t\t\t\tMonitor.warn('Dropping malformed usergroups line (missing ID):');\r\n\t\t\t\tMonitor.warn(row);\r\n\t\t\t\tcontinue;\r\n\t\t\t}\r\n\t\t\tthis.usernames.set(id, name);\r\n\t\t\tif (sectionid) this.sectionLeaders.set(id, sectionid as RoomSection);\r\n\r\n\t\t\t// handle glitched entries where a user has two entries in usergroups.csv due to bugs\r\n\t\t\tconst newSymbol = symbol.charAt(0) as GroupSymbol;\r\n\t\t\t// Yes, we HAVE to ensure that it exists in the super. super.get here returns either the group symbol,\r\n\t\t\t// or the default symbol if it cannot find a symbol in the map.\r\n\t\t\t// the default symbol is truthy, and the symbol for trusted user is ` `\r\n\t\t\t// meaning that the preexisting && atLeast would return true, which would skip the row and nuke all trusted users\r\n\t\t\t// on a fresh load (aka, a restart).\r\n\t\t\tconst preexistingSymbol = super.has(id) ? super.get(id) : null;\r\n\t\t\t// take a user's highest rank in usergroups.csv\r\n\t\t\tif (preexistingSymbol && Auth.atLeast(preexistingSymbol, newSymbol)) continue;\r\n\t\t\tsuper.set(id, newSymbol);\r\n\t\t}\r\n\t}\r\n\tset(id: ID, group: GroupSymbol, username?: string) {\r\n\t\tif (!username) username = id;\r\n\t\tconst user = Users.get(id, true);\r\n\t\tif (user) {\r\n\t\t\tuser.tempGroup = group;\r\n\t\t\tuser.updateIdentity();\r\n\t\t\tusername = user.name;\r\n\t\t\tRooms.global.checkAutojoin(user);\r\n\t\t}\r\n\t\tthis.usernames.set(id, username);\r\n\t\tsuper.set(id, group);\r\n\t\tvoid this.save();\r\n\t\treturn this;\r\n\t}\r\n\tdelete(id: ID) {\r\n\t\tif (!super.has(id)) return false;\r\n\t\tsuper.delete(id);\r\n\t\tconst user = Users.get(id);\r\n\t\tif (user) {\r\n\t\t\tuser.tempGroup = ' ';\r\n\t\t}\r\n\t\tthis.usernames.delete(id);\r\n\t\tthis.save();\r\n\t\treturn true;\r\n\t}\r\n\tsetSection(id: ID, sectionid: RoomSection, username?: string) {\r\n\t\tif (!username) username = id;\r\n\t\tconst user = Users.get(id);\r\n\t\tif (user) {\r\n\t\t\tuser.updateIdentity();\r\n\t\t\tusername = user.name;\r\n\t\t\tRooms.global.checkAutojoin(user);\r\n\t\t}\r\n\t\tif (!super.has(id)) this.set(id, ' ', username);\r\n\t\tthis.sectionLeaders.set(id, sectionid);\r\n\t\tvoid this.save();\r\n\t\treturn this;\r\n\t}\r\n\tdeleteSection(id: ID) {\r\n\t\tif (!this.sectionLeaders.has(id)) return false;\r\n\t\tthis.sectionLeaders.delete(id);\r\n\t\tif (super.get(id) === ' ') {\r\n\t\t\treturn this.delete(id);\r\n\t\t}\r\n\t\tconst user = Users.get(id);\r\n\t\tif (user) {\r\n\t\t\tuser.updateIdentity();\r\n\t\t\tRooms.global.checkAutojoin(user);\r\n\t\t}\r\n\t\tthis.save();\r\n\t\treturn true;\r\n\t}\r\n}\r\n"], "mappings": "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", "names": [] }