omegga 1.2.8 → 1.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (255) hide show
  1. package/README.md +20 -1
  2. package/dist/brickadia/config.js +26 -90
  3. package/dist/brickadia/config.js.map +1 -1
  4. package/dist/brickadia/server.js +294 -293
  5. package/dist/brickadia/server.js.map +1 -1
  6. package/dist/cli/auth.js +149 -177
  7. package/dist/cli/auth.js.map +1 -1
  8. package/dist/cli/config.js +64 -66
  9. package/dist/cli/config.js.map +1 -1
  10. package/dist/cli/index.js +14 -14
  11. package/dist/cli/index.js.map +1 -1
  12. package/dist/cli/installer.js +37 -43
  13. package/dist/cli/installer.js.map +1 -1
  14. package/dist/cli/plugin.js +651 -682
  15. package/dist/cli/plugin.js.map +1 -1
  16. package/dist/cli/terminal.js +811 -733
  17. package/dist/cli/terminal.js.map +1 -1
  18. package/dist/config/formats/format_js.js +6 -6
  19. package/dist/config/formats/format_js.js.map +1 -1
  20. package/dist/config/formats/format_yml.js +7 -10
  21. package/dist/config/formats/format_yml.js.map +1 -1
  22. package/dist/config/index.js +46 -68
  23. package/dist/config/index.js.map +1 -1
  24. package/dist/config/reader.js +16 -27
  25. package/dist/config/reader.js.map +1 -1
  26. package/dist/config/validator.js +23 -25
  27. package/dist/config/validator.js.map +1 -1
  28. package/dist/config/writer.js +11 -21
  29. package/dist/config/writer.js.map +1 -1
  30. package/dist/index.js +18 -64
  31. package/dist/index.js.map +1 -1
  32. package/dist/info/default_commands.json.js +39 -0
  33. package/dist/info/default_commands.json.js.map +1 -0
  34. package/dist/logger.js +61 -60
  35. package/dist/logger.js.map +1 -1
  36. package/dist/main.js +424 -471
  37. package/dist/main.js.map +1 -1
  38. package/dist/omegga/auth.js +101 -148
  39. package/dist/omegga/auth.js.map +1 -1
  40. package/dist/omegga/commandInjector.js +261 -251
  41. package/dist/omegga/commandInjector.js.map +1 -1
  42. package/dist/omegga/index.js +14 -52
  43. package/dist/omegga/index.js.map +1 -1
  44. package/dist/omegga/logWrangler.js +224 -275
  45. package/dist/omegga/logWrangler.js.map +1 -1
  46. package/dist/omegga/matchers/auth.js +36 -50
  47. package/dist/omegga/matchers/auth.js.map +1 -1
  48. package/dist/omegga/matchers/chat.js +49 -71
  49. package/dist/omegga/matchers/chat.js.map +1 -1
  50. package/dist/omegga/matchers/command.js +25 -36
  51. package/dist/omegga/matchers/command.js.map +1 -1
  52. package/dist/omegga/matchers/exit.js +15 -18
  53. package/dist/omegga/matchers/exit.js.map +1 -1
  54. package/dist/omegga/matchers/index.js +26 -40
  55. package/dist/omegga/matchers/index.js.map +1 -1
  56. package/dist/omegga/matchers/init.js +20 -23
  57. package/dist/omegga/matchers/init.js.map +1 -1
  58. package/dist/omegga/matchers/interact.js +58 -64
  59. package/dist/omegga/matchers/interact.js.map +1 -1
  60. package/dist/omegga/matchers/join.js +74 -95
  61. package/dist/omegga/matchers/join.js.map +1 -1
  62. package/dist/omegga/matchers/leave.js +43 -56
  63. package/dist/omegga/matchers/leave.js.map +1 -1
  64. package/dist/omegga/matchers/mapChange.js +26 -35
  65. package/dist/omegga/matchers/mapChange.js.map +1 -1
  66. package/dist/omegga/matchers/minigameJoin.js +24 -31
  67. package/dist/omegga/matchers/minigameJoin.js.map +1 -1
  68. package/dist/omegga/matchers/version.js +42 -49
  69. package/dist/omegga/matchers/version.js.map +1 -1
  70. package/dist/omegga/player.js +527 -527
  71. package/dist/omegga/player.js.map +1 -1
  72. package/dist/omegga/plugin/interface.js +91 -98
  73. package/dist/omegga/plugin/interface.js.map +1 -1
  74. package/dist/omegga/plugin/plugin_jsonrpc_stdio.js +524 -429
  75. package/dist/omegga/plugin/plugin_jsonrpc_stdio.js.map +1 -1
  76. package/dist/omegga/plugin/plugin_node_safe/proxyOmegga.js +282 -294
  77. package/dist/omegga/plugin/plugin_node_safe/proxyOmegga.js.map +1 -1
  78. package/dist/omegga/plugin/plugin_node_safe.js +365 -393
  79. package/dist/omegga/plugin/plugin_node_safe.js.map +1 -1
  80. package/dist/omegga/plugin/plugin_node_unsafe.js +119 -179
  81. package/dist/omegga/plugin/plugin_node_unsafe.js.map +1 -1
  82. package/dist/omegga/plugin.js +402 -347
  83. package/dist/omegga/plugin.js.map +1 -1
  84. package/dist/omegga/server.js +742 -774
  85. package/dist/omegga/server.js.map +1 -1
  86. package/dist/omegga/wrapper.js +64 -91
  87. package/dist/omegga/wrapper.js.map +1 -1
  88. package/dist/plugin.js +11 -31
  89. package/dist/plugin.js.map +1 -1
  90. package/dist/softconfig.js +121 -100
  91. package/dist/softconfig.js.map +1 -1
  92. package/dist/updater/steam.js +97 -112
  93. package/dist/updater/steam.js.map +1 -1
  94. package/dist/util/brdb.js +496 -528
  95. package/dist/util/brdb.js.map +1 -1
  96. package/dist/util/brick/checkBounds.js +11 -15
  97. package/dist/util/brick/checkBounds.js.map +1 -1
  98. package/dist/util/brick/constants.js +723 -174
  99. package/dist/util/brick/constants.js.map +1 -1
  100. package/dist/util/brick/displayName.js +204 -211
  101. package/dist/util/brick/displayName.js.map +1 -1
  102. package/dist/util/brick/getBounds.js +29 -41
  103. package/dist/util/brick/getBounds.js.map +1 -1
  104. package/dist/util/brick/getBrickSize.js +6 -7
  105. package/dist/util/brick/getBrickSize.js.map +1 -1
  106. package/dist/util/brick/getScaleAxis.js +24 -30
  107. package/dist/util/brick/getScaleAxis.js.map +1 -1
  108. package/dist/util/brick/index.js +8 -29
  109. package/dist/util/brick/index.js.map +1 -1
  110. package/dist/util/brick/rotate.js +29 -34
  111. package/dist/util/brick/rotate.js.map +1 -1
  112. package/dist/util/brick/setOwnership.js +13 -19
  113. package/dist/util/brick/setOwnership.js.map +1 -1
  114. package/dist/util/chat.js +53 -44
  115. package/dist/util/chat.js.map +1 -1
  116. package/dist/util/color.js +112 -124
  117. package/dist/util/color.js.map +1 -1
  118. package/dist/util/file.js +54 -98
  119. package/dist/util/file.js.map +1 -1
  120. package/dist/util/index.js +84 -106
  121. package/dist/util/index.js.map +1 -1
  122. package/dist/util/map.js +18 -20
  123. package/dist/util/map.js.map +1 -1
  124. package/dist/util/pattern.js +6 -9
  125. package/dist/util/pattern.js.map +1 -1
  126. package/dist/util/time.js +31 -34
  127. package/dist/util/time.js.map +1 -1
  128. package/dist/util/uuid.js +10 -8
  129. package/dist/util/uuid.js.map +1 -1
  130. package/dist/util/wsl.js +19 -25
  131. package/dist/util/wsl.js.map +1 -1
  132. package/dist/version.js +7 -9
  133. package/dist/version.js.map +1 -1
  134. package/dist/webserver/backend/api.js +784 -874
  135. package/dist/webserver/backend/api.js.map +1 -1
  136. package/dist/webserver/backend/calendar.js +14 -17
  137. package/dist/webserver/backend/calendar.js.map +1 -1
  138. package/dist/webserver/backend/database.js +563 -613
  139. package/dist/webserver/backend/database.js.map +1 -1
  140. package/dist/webserver/backend/index.js +153 -191
  141. package/dist/webserver/backend/index.js.map +1 -1
  142. package/dist/webserver/backend/metrics.js +219 -248
  143. package/dist/webserver/backend/metrics.js.map +1 -1
  144. package/dist/webserver/backend/util.js +47 -68
  145. package/dist/webserver/backend/util.js.map +1 -1
  146. package/dist/worker.js +322 -0
  147. package/dist/worker.js.map +1 -0
  148. package/package.json +14 -10
  149. package/templates/safe-ts/omegga.d.ts +2 -2
  150. package/vite.backend.config.mts +46 -0
  151. package/vite.frontend.config.mts +58 -0
  152. package/vitest.backend.config.mts +7 -0
  153. package/dist/brickadia/config.d.ts +0 -3
  154. package/dist/brickadia/presets.d.ts +0 -65
  155. package/dist/brickadia/presets.js +0 -3
  156. package/dist/brickadia/presets.js.map +0 -1
  157. package/dist/brickadia/server.d.ts +0 -36
  158. package/dist/brickadia/types.d.ts +0 -45
  159. package/dist/brickadia/types.js +0 -3
  160. package/dist/brickadia/types.js.map +0 -1
  161. package/dist/cli/auth.d.ts +0 -26
  162. package/dist/cli/config.d.ts +0 -10
  163. package/dist/cli/index.d.ts +0 -30
  164. package/dist/cli/installer.d.ts +0 -1
  165. package/dist/cli/plugin.d.ts +0 -22
  166. package/dist/cli/terminal.d.ts +0 -25
  167. package/dist/config/authorizer.d.ts +0 -2
  168. package/dist/config/authorizer.js +0 -38
  169. package/dist/config/authorizer.js.map +0 -1
  170. package/dist/config/formats/format_js.d.ts +0 -3
  171. package/dist/config/formats/format_yml.d.ts +0 -3
  172. package/dist/config/index.d.ts +0 -18
  173. package/dist/config/reader.d.ts +0 -3
  174. package/dist/config/types.d.ts +0 -50
  175. package/dist/config/types.js +0 -3
  176. package/dist/config/types.js.map +0 -1
  177. package/dist/config/validator.d.ts +0 -6
  178. package/dist/config/writer.d.ts +0 -3
  179. package/dist/index.d.ts +0 -22
  180. package/dist/info/default_commands.json +0 -29
  181. package/dist/logger.d.ts +0 -41
  182. package/dist/main.d.ts +0 -1
  183. package/dist/omegga/auth.d.ts +0 -9
  184. package/dist/omegga/commandInjector.d.ts +0 -35
  185. package/dist/omegga/index.d.ts +0 -7
  186. package/dist/omegga/logWrangler.d.ts +0 -32
  187. package/dist/omegga/matchers/auth.d.ts +0 -10
  188. package/dist/omegga/matchers/chat.d.ts +0 -10
  189. package/dist/omegga/matchers/command.d.ts +0 -7
  190. package/dist/omegga/matchers/exit.d.ts +0 -3
  191. package/dist/omegga/matchers/index.d.ts +0 -3
  192. package/dist/omegga/matchers/init.d.ts +0 -3
  193. package/dist/omegga/matchers/interact.d.ts +0 -4
  194. package/dist/omegga/matchers/join.d.ts +0 -4
  195. package/dist/omegga/matchers/leave.d.ts +0 -4
  196. package/dist/omegga/matchers/mapChange.d.ts +0 -3
  197. package/dist/omegga/matchers/minigameJoin.d.ts +0 -9
  198. package/dist/omegga/matchers/types.d.ts +0 -5
  199. package/dist/omegga/matchers/types.js +0 -3
  200. package/dist/omegga/matchers/types.js.map +0 -1
  201. package/dist/omegga/matchers/version.d.ts +0 -3
  202. package/dist/omegga/player.d.ts +0 -81
  203. package/dist/omegga/plugin/interface.d.ts +0 -30
  204. package/dist/omegga/plugin/plugin_jsonrpc_stdio.d.ts +0 -23
  205. package/dist/omegga/plugin/plugin_node_safe/proxyOmegga.d.ts +0 -145
  206. package/dist/omegga/plugin/plugin_node_safe/worker.d.ts +0 -1
  207. package/dist/omegga/plugin/plugin_node_safe/worker.js +0 -367
  208. package/dist/omegga/plugin/plugin_node_safe/worker.js.map +0 -1
  209. package/dist/omegga/plugin/plugin_node_safe.d.ts +0 -23
  210. package/dist/omegga/plugin/plugin_node_unsafe.d.ts +0 -13
  211. package/dist/omegga/plugin.d.ts +0 -63
  212. package/dist/omegga/server.d.ts +0 -166
  213. package/dist/omegga/types.d.ts +0 -49
  214. package/dist/omegga/types.js +0 -3
  215. package/dist/omegga/types.js.map +0 -1
  216. package/dist/omegga/wrapper.d.ts +0 -32
  217. package/dist/plugin.d.ts +0 -916
  218. package/dist/softconfig.d.ts +0 -67
  219. package/dist/tsconfig.tsbuildinfo +0 -1
  220. package/dist/updater/index.d.ts +0 -1
  221. package/dist/updater/index.js +0 -10
  222. package/dist/updater/index.js.map +0 -1
  223. package/dist/updater/steam.d.ts +0 -52
  224. package/dist/util/brdb.d.ts +0 -31
  225. package/dist/util/brick/checkBounds.d.ts +0 -8
  226. package/dist/util/brick/constants.d.ts +0 -18
  227. package/dist/util/brick/displayName.d.ts +0 -7
  228. package/dist/util/brick/getBounds.d.ts +0 -5
  229. package/dist/util/brick/getBrickSize.d.ts +0 -3
  230. package/dist/util/brick/getScaleAxis.d.ts +0 -3
  231. package/dist/util/brick/index.d.ts +0 -14
  232. package/dist/util/brick/rotate.d.ts +0 -16
  233. package/dist/util/brick/setOwnership.d.ts +0 -12
  234. package/dist/util/chat.d.ts +0 -23
  235. package/dist/util/color.d.ts +0 -13
  236. package/dist/util/file.d.ts +0 -5
  237. package/dist/util/index.d.ts +0 -183
  238. package/dist/util/map.d.ts +0 -6
  239. package/dist/util/pattern.d.ts +0 -1
  240. package/dist/util/time.d.ts +0 -39
  241. package/dist/util/uuid.d.ts +0 -3
  242. package/dist/util/wsl.d.ts +0 -2
  243. package/dist/version.d.ts +0 -2
  244. package/dist/webserver/backend/api.d.ts +0 -115
  245. package/dist/webserver/backend/calendar.d.ts +0 -5
  246. package/dist/webserver/backend/database.d.ts +0 -150
  247. package/dist/webserver/backend/index.d.ts +0 -30
  248. package/dist/webserver/backend/metrics.d.ts +0 -3
  249. package/dist/webserver/backend/types.d.ts +0 -114
  250. package/dist/webserver/backend/types.js +0 -3
  251. package/dist/webserver/backend/types.js.map +0 -1
  252. package/dist/webserver/backend/util.d.ts +0 -2
  253. package/dist/webserver/index.d.ts +0 -2
  254. package/dist/webserver/index.js +0 -9
  255. package/dist/webserver/index.js.map +0 -1
@@ -1 +1 @@
1
- {"version":3,"file":"database.js","sourceRoot":"","sources":["../../../src/webserver/backend/database.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"database.js","sources":["../../../src/webserver/backend/database.ts"],"sourcesContent":["import soft from '@/softconfig';\nimport { IServerConfig } from '@config/types';\nimport type Omegga from '@omegga/server';\nimport { explode } from '@util/pattern';\nimport { parseBrickadiaTime } from '@util/time';\nimport bcrypt from 'bcryptjs';\nimport chokidar from 'chokidar';\nimport EventEmitter from 'events';\nimport Datastore from 'nedb-promises';\nimport path from 'path';\nimport Calendar from './calendar';\nimport {\n IPlayer,\n IPunchcard,\n IStoreAutoRestartConfig,\n IStoreBanHistory,\n IStoreChat,\n IStoreKickHistory,\n IStoreServerInstance,\n IStoreUser,\n IStoreVersion,\n IUserHistory,\n IUserNote,\n} from './types';\n\n// TODO: online users graph\n// TODO: player online times\n// TODO: bricks over time graph\n// TODO: minute server status for metrics\n// TODO: chat messages per min/hour/day check\n\nlet serverInstance: IStoreServerInstance & { _id: string };\n\ntype FixedSizeArray<N extends number, T, M extends string = '0'> = {\n readonly [k in M]: any;\n} & { length: N } & ReadonlyArray<T>;\n\n// generate a punchcard (days x week)\nconst createPunchcard = (): number[][] =>\n Array.from({ length: 7 }).map(() =>\n Array.from<number>({ length: 24 }).fill(0),\n );\n\n// the database keeps track of metrics for omegga\nexport default class Database extends EventEmitter {\n options: IServerConfig;\n omegga: Omegga;\n stores: {\n users: Datastore;\n chat: Datastore;\n players: Datastore;\n status: Datastore;\n server: Datastore;\n };\n calendar: Calendar;\n\n constructor(options: IServerConfig, omegga: Omegga) {\n super();\n this.options = options;\n this.omegga = omegga;\n this.calendar = new Calendar();\n\n // database\n const dbOpts = {\n autoload: true,\n // case insensitive string comparison\n compareStrings: (a: string, b: string) =>\n a.localeCompare(b, 'en', { ignorePunctuation: true }),\n };\n\n // create all the stores\n this.stores = {\n users: Datastore.create({\n filename: path.join(omegga.dataPath, soft.USER_STORE),\n ...dbOpts,\n }),\n chat: Datastore.create({\n filename: path.join(omegga.dataPath, soft.CHAT_STORE),\n ...dbOpts,\n }),\n players: Datastore.create({\n filename: path.join(omegga.dataPath, soft.PLAYER_STORE),\n ...dbOpts,\n }),\n status: Datastore.create({\n filename: path.join(omegga.dataPath, soft.STATUS_STORE),\n ...dbOpts,\n }),\n server: Datastore.create({\n filename: path.join(omegga.dataPath, soft.SERVER_STORE),\n ...dbOpts,\n }),\n };\n }\n\n // make sure all the databases have valid store versions\n async doMigrations() {\n // current store versions\n const storeVersions: { [key: keyof typeof this.stores]: number } = {\n users: 1,\n chat: 1,\n players: 1,\n status: 1,\n server: 1,\n\n // example version\n dummy: 10,\n };\n\n // migrations to/from certain store versions\n const migrations: {\n [key: keyof typeof this.stores]: {\n version: number;\n upgrade: (store: Datastore) => Promise<void>;\n }[];\n } = {\n users: [],\n chat: [],\n players: [],\n status: [],\n server: [],\n\n // example migration list (all version upgrades go up by 1)\n dummy: [\n {\n version: 1, // target version\n upgrade: async _store => {}, // upgrade function (does not include updating version)\n },\n ],\n };\n\n // loop through all stores to find if any need version upgrades\n await Promise.all(\n Object.entries(this.stores).map(async ([name, store]) => {\n const versionEntry = await store.findOne<IStoreVersion>({\n type: 'storeVersion',\n });\n const expected = storeVersions[name];\n // if the version was not found, insert it\n if (!versionEntry) {\n store.insert({ type: 'storeVersion', version: expected });\n\n // if the version was not what was expected\n } else if (expected !== versionEntry.version) {\n // while the version is below the expected version\n let { version } = versionEntry;\n for (; version < expected; version++) {\n // find an available migration\n const migration = migrations[name].find(v => v.version === version);\n\n // no migration found, ignore\n if (!migration) break;\n\n // run the upgrade\n migration.upgrade(store);\n }\n\n // update the stored version\n await store.update({ _id: versionEntry._id }, { version });\n }\n }),\n );\n }\n\n // get the running instance id of this omegga\n async getInstanceId() {\n if (serverInstance) return serverInstance._id;\n\n const doc = await this.stores.server.insert<IStoreServerInstance>({\n type: 'app:start',\n date: Date.now(),\n });\n\n serverInstance = doc;\n\n // create a calendar of all previous chat messages\n const dates = (\n await this.stores.chat.find<IStoreChat>({ type: 'chat' })\n ).map(c => c.created);\n for (const d of dates) {\n this.calendar.addDate(d);\n }\n\n const watcher = chokidar.watch(\n path.join(this.omegga.configPath, 'BanList.json'),\n { persistent: false },\n );\n watcher\n .on('add', () => setTimeout(this.syncBanList.bind(this), 500))\n .on('change', () =>\n setTimeout(() => {\n this.syncBanList();\n this.emit('update.bans');\n }, 500),\n );\n setTimeout(this.syncBanList.bind(this), 500);\n\n const handleKick = (kicked: IPlayer, kicker: IPlayer, reason: string) => {\n // time the event listener should expire\n const eventExpire = Date.now() + 100;\n\n // detect a single leave\n this.omegga.once('leave', async leavingPlayer => {\n const now = Date.now();\n // if a player leaves more than 100ms from the kick command, it's bugged\n if (now > eventExpire) return;\n\n if (leavingPlayer.id === kicked.id) {\n const entry = {\n type: 'kickHistory',\n kicked: kicked.id,\n kickerId: kicker.id,\n created: now,\n reason,\n };\n\n // depending on implementation, this could potentially be a kick event\n await this.stores.players.update(\n entry,\n { $set: entry },\n { upsert: true },\n );\n }\n });\n };\n\n // for a5 is based on the chat event\n this.omegga.on('kick', (kicked, kicker, reason) => {\n const kickedPlayer = this.omegga.findPlayerByName(kicked);\n const kickerPlayer = this.omegga.findPlayerByName(kicker);\n\n // couldn't find kicked or kicker player\n if (!kickedPlayer || !kickerPlayer) return;\n\n handleKick(kickedPlayer, kickerPlayer, reason);\n });\n\n return doc._id;\n }\n\n // synchronize the ban list with the one in the database\n syncBanList() {\n const banList = this.omegga.getBanList()?.banList;\n if (!banList) return;\n\n // upsert all bans\n for (const banned in banList) {\n const entry: IStoreBanHistory = {\n type: 'banHistory',\n banned,\n bannerId: banList[banned].bannerId,\n created: parseBrickadiaTime(banList[banned].created),\n expires: parseBrickadiaTime(banList[banned].expires),\n reason: banList[banned].reason,\n };\n\n this.stores.players.update(entry, { $set: entry }, { upsert: true });\n }\n }\n\n // determine if this user would be the first user (admin user)\n async isFirstUser() {\n return (await this.stores.users.count({ type: 'user' })) === 0;\n }\n\n // hash a password\n async hash(password: string) {\n return await bcrypt.hash(password, 10);\n }\n\n // create an admin user account, username can be blank (no password)\n async createAdminUser(username: string, password: string) {\n const hash = await this.hash(password);\n\n // create an owner user\n const user = this.stores.users.insert({\n // this is a user\n type: 'user',\n created: Date.now(),\n lastOnline: Date.now(),\n\n // credentials\n username,\n hash,\n\n // permissions\n isOwner: true,\n roles: [],\n\n // brickadia player uuid\n playerId: '',\n });\n return user;\n }\n\n // determine if a user with this name exists\n async userExists(username: string) {\n return (await this.stores.users.count({ type: 'user', username })) > 0;\n }\n\n // create a regular user account\n async createUser(username: string, password: string) {\n if (await this.userExists(username)) throw new Error('user already exists');\n\n const hash = await this.hash(password);\n // create an owner user\n const user = this.stores.users.insert<IStoreUser>({\n // this is a user\n type: 'user',\n created: Date.now(),\n lastOnline: 0,\n\n // credentials\n username,\n hash,\n\n // permissions\n isOwner: false,\n roles: [],\n\n // brickadia player uuid\n playerId: '',\n });\n return user;\n }\n\n // set a user's password\n async userPasswd(username: string, password: string) {\n const hash = await this.hash(password);\n\n if (!this.userExists(username)) throw new Error('user does not exist');\n\n await this.stores.users.update(\n { type: 'user', username },\n { $set: { hash } },\n );\n }\n\n // get a user from credentials\n async authUser(username: string, password: string) {\n const user = await this.stores.users.findOne<IStoreUser>({ username });\n // user not found\n if (!user || user.isBanned) return null;\n\n // make sure the user's password hash is valid\n if (await bcrypt.compare(password, user.hash)) {\n // update last online status\n await this.stores.users.update(\n { _id: user._id },\n { $set: { lastOnline: Date.now() } },\n );\n return user;\n }\n\n // wrong password\n return null;\n }\n\n // find a user by object id\n async findUserById(id: string) {\n return await this.stores.users.findOne<IStoreUser>({\n $or: [\n // the owner has no username, so everyone is the owner\n { type: 'user', username: '', isOwner: true },\n\n // the user exists and has an id\n { type: 'user', _id: id },\n ],\n });\n }\n\n // get a list of roles\n // TODO: actually implement roles\n getRoles(): Promise<{ type: 'role'; name: 'string' }[]> {\n return this.stores.server.find({ type: 'role' });\n }\n\n // add a chat message to the chat log store\n async addChatLog(\n action: 'msg' | 'server' | 'leave' | 'join',\n user: IPlayer,\n message?: string,\n ) {\n this.calendar.addDate(Date.now());\n return await this.stores.chat.insert<IStoreChat>({\n type: 'chat',\n created: Date.now(),\n instanceId: await this.getInstanceId(),\n action,\n user,\n ...(message ? { message } : {}),\n });\n }\n\n // get recent chat activity\n async getChats({\n count = 50,\n sameServer,\n before,\n after,\n }: {\n count?: number;\n sameServer?: boolean;\n before?: number;\n after?: number;\n } = {}) {\n return await this.stores.chat\n .find<IStoreChat>({\n type: 'chat',\n ...(sameServer ? { instanceId: await this.getInstanceId() } : {}),\n created: before\n ? { $lt: before }\n : after\n ? { $gt: after }\n : { $lt: Date.now() },\n })\n .sort({ created: !before && after ? 1 : -1 })\n .limit(count)\n .exec();\n }\n\n // get paginated players\n async getPlayers({\n count = 50,\n search = '',\n page = 0,\n sort = 'name',\n direction = '1',\n limitId = undefined,\n }: {\n count?: number;\n search?: string;\n page?: number;\n sort?: string;\n direction?: string;\n limitId?: string[];\n } = {}) {\n const pattern = explode(search);\n\n // the query used for finding which players are available\n const query = {\n type: 'userHistory',\n // only filter if there's a query\n $and: [\n // if a limitId is passed in, the id must be in it\n ...(limitId ? [{ id: { $in: limitId } }] : []),\n\n // if there's a search, the search matches...\n ...(search.length > 0\n ? [\n {\n $or: [\n // id was pasted in\n { id: search },\n // user's current name\n { name: { $regex: pattern } },\n { displayName: { $regex: pattern } },\n // user's past name\n {\n nameHistory: { $elemMatch: { name: { $regex: pattern } } },\n },\n {\n nameHistory: {\n $elemMatch: { displayName: { $regex: pattern } },\n },\n },\n ],\n },\n ]\n : []),\n ],\n };\n\n // the query used for finding a specific player\n const exactQuery = {\n type: 'userHistory',\n // only filter if there's a query\n $or: [\n // id was pasted in\n { id: search },\n // user's current name\n { name: search },\n // user's current display name\n { displayName: search },\n ],\n };\n\n // count players and query players\n const [total, players, exactResult] = await Promise.all([\n this.stores.players.count(query),\n this.stores.players\n .find<IUserHistory>(query)\n // TODO: add other sorts and sort directions\n .sort({ [sort]: direction })\n .skip(count * page)\n .limit(count)\n .exec(),\n\n // exact match detection\n search.length > 0 && page === 0\n ? this.stores.players.find(exactQuery)\n : [],\n ]);\n\n // add exact matches to the beginning\n if (exactResult.length > 0) {\n // remove duplicates\n for (const res of exactResult) {\n const index = players.findIndex(p => p._id === res._id);\n players.splice(index, 1);\n }\n\n // add results to the beginning\n players.splice(0, 0, ...exactResult);\n }\n\n return {\n pages: Math.ceil(total / count),\n total,\n players,\n };\n }\n\n // get paginated users\n async getUsers({\n count = 50,\n search = '',\n page = 0,\n sort = 'name',\n direction = '1',\n } = {}) {\n const pattern = explode(search);\n\n // the query used for finding which players are available\n const query = {\n type: 'user',\n // only filter if there's a query\n ...(search.length > 0\n ? {\n $or: [\n // id was pasted in\n { playerId: search },\n // user's current name\n { name: { $regex: pattern } },\n ],\n }\n : {}),\n };\n\n // count players and query players\n const [total, users] = await Promise.all([\n this.stores.users.count(query),\n this.stores.users\n .find<IStoreUser>(query)\n // TODO: add other sorts and sort directions\n .sort({ [sort]: direction })\n .skip(count * page)\n .limit(count)\n .exec(),\n ]);\n\n return {\n pages: Math.ceil(total / count),\n total,\n users,\n };\n }\n\n // get an individual player, ban and kick history, and notes\n async getPlayer(id: string) {\n const [player, banHistory, kickHistory, notes] = await Promise.all([\n this.stores.players.findOne<IUserHistory>({ type: 'userHistory', id }),\n this.stores.players\n .find<IStoreBanHistory>({ type: 'banHistory', banned: id })\n .sort({ created: -1 })\n .limit(25)\n .exec(),\n this.stores.players\n .find<IStoreKickHistory>({ type: 'kickHistory', kicked: id })\n .sort({ created: -1 })\n .limit(25)\n .exec(),\n this.stores.players\n .find<IUserNote>({ type: 'note', id })\n .sort({ created: -1 })\n .limit(25)\n .exec(),\n ]);\n\n if (!player) return null;\n\n return { ...player, banHistory, kickHistory, notes };\n }\n\n // add a user to the visit history, returns true if this is a first visit\n async addVisit(user: IPlayer) {\n const existing = await this.stores.players.findOne<IUserHistory>({\n type: 'userHistory',\n id: user.id,\n });\n const now = Date.now();\n const instanceId = await this.getInstanceId();\n if (!existing) {\n // create the player\n // TODO: add some form of admin note tool for moderators to leave notes\n // on troublesome players + warnings\n await this.stores.players.insert<IUserHistory>({\n type: 'userHistory',\n // base brickadia user info\n id: user.id,\n name: user.name,\n displayName: user.displayName,\n // list of names and when they were first used\n nameHistory: [\n { name: user.name, displayName: user.displayName, date: now },\n ],\n // list of ips this player has been on\n ips: [],\n // first time player was seen\n created: now,\n // last time player was seen\n lastSeen: now,\n // last server this player has been on\n lastInstanceId: instanceId,\n // number of status checks this player has observed\n heartbeats: 0,\n // number of sessions (at least an hour apart) this player has had\n sessions: 1,\n // number of instances (times omegga was started) this player has joined\n instances: 1,\n });\n return true;\n } else {\n await this.stores.players.update<IUserHistory>(\n { _id: existing._id },\n {\n $inc: {\n // increment number of sessions if the player hasn't been seen for an hour\n sessions: existing.lastSeen < now - 60 * 60 * 1000 ? 1 : 0,\n // increment the number of instances this player has joined\n instances: existing.lastInstanceId === instanceId ? 1 : 0,\n },\n\n $set: {\n // update last seen time and user name\n lastSeen: now,\n name: user.name,\n displayName: user.displayName,\n\n // set the last joined instance\n lastInstanceId: instanceId,\n },\n\n // add the name to the history if it was not already in it\n ...(existing.nameHistory.some(\n h => h.name === user.name && h.displayName === user.displayName,\n )\n ? {}\n : {\n $addToSet: {\n nameHistory: {\n name: user.name,\n displayName: user.displayName,\n date: now,\n },\n },\n }),\n },\n );\n return false;\n }\n }\n\n // use data from minutely heartbeats to fuel metrics\n async addHeartbeat(data: {\n bricks: number;\n players: string[];\n ips: Record<string, string>;\n }) {\n const now = Date.now();\n\n // add the heartbeat to the server status store\n await this.stores.status.insert({\n type: 'heartbeat',\n created: now,\n bricks: data.bricks,\n players: data.players,\n });\n\n // update player heartbeats and last seens\n await this.stores.players.update(\n {\n // all players in the status update\n id: { $in: data.players },\n },\n {\n // update last seen\n $set: { lastSeen: now },\n // increment heartbeats\n $inc: { heartbeats: 1 },\n },\n { multi: true },\n );\n\n // get all players in the status update\n const players = await this.stores.players.find<IUserHistory>({\n id: { $in: data.players },\n });\n\n await Promise.all(\n players\n // find players without the discovered ip\n .filter(p => !(p.ips || []).includes(data.ips[p.id]))\n // insert the IP into the player's ip list\n .map(p =>\n this.stores.players.update(\n { _id: p._id },\n {\n $addToSet: { ips: data.ips[p.id] },\n },\n ),\n ),\n );\n }\n\n async getAutoRestartConfig(): Promise<IStoreAutoRestartConfig> {\n let config = await this.stores.server.findOne<IStoreAutoRestartConfig>({\n type: 'autoRestartConfig',\n });\n if (!config) {\n config = await this.stores.server.insert({\n type: 'autoRestartConfig',\n maxUptime: 48,\n maxUptimeEnabled: false,\n emptyUptime: 24,\n emptyUptimeEnabled: false,\n dailyHour: 2,\n dailyHourEnabled: false,\n autoUpdateEnabled: true,\n autoUpdateIntervalMins: 60,\n announcementEnabled: true,\n playersEnabled: true,\n saveWorld: true,\n });\n }\n\n config.autoUpdateEnabled ??= true;\n config.autoUpdateIntervalMins ??= 60;\n config.saveWorld ??= true;\n\n return config;\n }\n\n async setAutoRestartConfig(config: IStoreAutoRestartConfig): Promise<void> {\n config.maxUptime = Math.round(Math.max(1, Math.min(config.maxUptime, 168)));\n config.emptyUptime = Math.round(\n Math.max(1, Math.min(config.emptyUptime, 168)),\n );\n config.dailyHour = Math.round(Math.max(0, Math.min(config.dailyHour, 23)));\n config.autoUpdateIntervalMins = Math.round(\n Math.max(10, Math.min(config.autoUpdateIntervalMins ?? 60, Infinity)),\n );\n config.autoUpdateEnabled ??= true;\n await this.stores.server.update(\n { type: 'autoRestartConfig' },\n {\n $set: {\n ...config,\n },\n },\n { upsert: false },\n );\n }\n\n // update player online-time punchcard\n async updatePlayerPunchcard(numNewPlayers: number) {\n // get date, utc hour, and utc day\n const now = new Date();\n const time = now.getTime();\n const hour = now.getUTCHours();\n const day = now.getUTCDay();\n const month = now.getUTCMonth();\n const year = now.getUTCFullYear();\n\n // find the punchcard\n const card = await this.stores.status.findOne<IPunchcard>({\n type: 'punchcard',\n kind: 'playerCount',\n month,\n year,\n });\n\n // create a new punchcard if one does not exist for this month\n if (!card) {\n const punchcard = createPunchcard();\n punchcard[day][hour] = numNewPlayers;\n // insert it\n await this.stores.status.insert<IPunchcard>({\n type: 'punchcard',\n kind: 'playerCount',\n created: time,\n updated: time,\n month,\n year,\n punchcard,\n });\n\n // if the card exists, check if it was already updated this hour\n } else {\n // add the players to this slot\n card.punchcard[day][hour] += numNewPlayers;\n // update the punchcard\n await this.stores.status.update(\n { _id: card._id },\n {\n $set: {\n punchcard: card.punchcard,\n updated: time,\n },\n },\n );\n }\n }\n}\n"],"names":["Calendar","soft","parseBrickadiaTime","pattern","explode","time"],"mappings":"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"}
@@ -1,195 +1,157 @@
1
1
  "use strict";
2
- var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
- if (k2 === undefined) k2 = k;
4
- var desc = Object.getOwnPropertyDescriptor(m, k);
5
- if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
- desc = { enumerable: true, get: function() { return m[k]; } };
7
- }
8
- Object.defineProperty(o, k2, desc);
9
- }) : (function(o, m, k, k2) {
10
- if (k2 === undefined) k2 = k;
11
- o[k2] = m[k];
12
- }));
13
- var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
- Object.defineProperty(o, "default", { enumerable: true, value: v });
15
- }) : function(o, v) {
16
- o["default"] = v;
17
- });
18
- var __importStar = (this && this.__importStar) || (function () {
19
- var ownKeys = function(o) {
20
- ownKeys = Object.getOwnPropertyNames || function (o) {
21
- var ar = [];
22
- for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
23
- return ar;
24
- };
25
- return ownKeys(o);
26
- };
27
- return function (mod) {
28
- if (mod && mod.__esModule) return mod;
29
- var result = {};
30
- if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
31
- __setModuleDefault(result, mod);
32
- return result;
33
- };
34
- })();
35
- var __importDefault = (this && this.__importDefault) || function (mod) {
36
- return (mod && mod.__esModule) ? mod : { "default": mod };
37
- };
38
- Object.defineProperty(exports, "__esModule", { value: true });
39
- const logger_1 = __importDefault(require("../../logger"));
40
- const softconfig_1 = __importDefault(require("../../softconfig"));
41
- const body_parser_1 = __importDefault(require("body-parser"));
42
- const express_1 = __importDefault(require("express"));
43
- const express_session_1 = __importDefault(require("express-session"));
44
- const hasbin_1 = __importDefault(require("hasbin"));
45
- const http_1 = __importDefault(require("http"));
46
- const https_1 = __importDefault(require("https"));
47
- const nedb_promises_session_store_1 = __importDefault(require("nedb-promises-session-store"));
48
- const path_1 = __importDefault(require("path"));
49
- const socket_io_1 = require("socket.io");
50
- const api_1 = __importDefault(require("./api"));
51
- const database_1 = __importDefault(require("./database"));
52
- const metrics_1 = __importDefault(require("./metrics"));
53
- const util = __importStar(require("./util"));
54
- // path to vite-built data
55
- const PUBLIC_PATH = path_1.default.join(__dirname, '../../../public');
56
- const ASSETS_PATH = path_1.default.join(__dirname, '../../../public/assets');
57
- const log = (...args) => logger_1.default.log(...args);
58
- const error = (...args) => logger_1.default.error(...args);
59
- // the webserver servers an authenticated
2
+ Object.defineProperties(exports, { __esModule: { value: true }, [Symbol.toStringTag]: { value: "Module" } });
3
+ const logger = require("../../logger.js");
4
+ const softconfig = require("../../softconfig.js");
5
+ const bodyParser = require("body-parser");
6
+ const express = require("express");
7
+ const expressSession = require("express-session");
8
+ const hasbin = require("hasbin");
9
+ const http = require("http");
10
+ const https = require("https");
11
+ const NedbStore = require("nedb-promises-session-store");
12
+ const path = require("path");
13
+ const socket_io = require("socket.io");
14
+ const api = require("./api.js");
15
+ const database = require("./database.js");
16
+ const metrics = require("./metrics.js");
17
+ const util = require("./util.js");
18
+ const PUBLIC_PATH = path.join(__dirname, "../../../public");
19
+ const ASSETS_PATH = path.join(__dirname, "../../../public/assets");
20
+ const log = (...args) => logger.default.log(...args);
21
+ const error = (...args) => logger.default.error(...args);
60
22
  class Webserver {
61
- // create a webserver
62
- constructor(options, omegga) {
63
- this.port = Number(options.port || process.env.OMEGGA_PORT || softconfig_1.default.DEFAULT_PORT);
64
- this.options = options;
65
- this.omegga = omegga;
66
- this.dataPath = path_1.default.join(omegga.path, softconfig_1.default.DATA_PATH);
67
- // the database provides omegga with metrics, chat logs, and more
68
- // to help administrators keep track of their users and server
69
- this.database = new database_1.default(options, omegga);
70
- // https status of the server
71
- this.https = false;
72
- // started status of the server
73
- this.started = false;
74
- this.created = this.createServer();
75
- }
76
- // create the webserver
77
- async createServer() {
78
- const hasOpenSSL = hasbin_1.default.sync('openssl');
79
- // let the database do migrations
80
- await this.database.doMigrations();
81
- // create express app
82
- this.app = (0, express_1.default)();
83
- // create a server with https if applicable
84
- const pickProtocol = async () => {
85
- if (this.options.https) {
86
- if (hasOpenSSL) {
87
- const certFile = await util.getSSLKeys(this.dataPath);
88
- if (certFile) {
89
- // handy notification of generated ssl certs
90
- if (certFile.new)
91
- log('>>'.green, 'Generated new SSL certificate');
92
- this.https = true;
93
- return https_1.default.createServer({
94
- key: certFile.keys.serviceKey,
95
- cert: certFile.keys.certificate,
96
- }, this.app);
97
- }
98
- else {
99
- error('!>'.red, 'Error generating SSL certificate - falling back to http');
100
- }
101
- }
102
- // warn the user
103
- log(':>'.yellow, 'Running web server with http - install', 'openssl'.yellow.underline, 'for https (more secure)');
104
- }
105
- // fallback to http
106
- return new http_1.default.Server(this.app);
107
- };
108
- // create http(s) server based on openssl availability
109
- this.server = await pickProtocol();
110
- this.app.set('trust proxy', 1);
111
- const session = (0, express_session_1.default)({
112
- secret: util.getSessionSecret(this.dataPath),
113
- resave: false,
114
- saveUninitialized: false,
115
- cookie: {
116
- path: '/',
117
- secure: this.https,
118
- maxAge: 365 * 24 * 60 * 60 * 1000, // 1 year
119
- },
120
- // use a nedb database for session store
121
- store: (0, nedb_promises_session_store_1.default)({
122
- filename: path_1.default.join(this.dataPath, softconfig_1.default.SESSION_STORE),
123
- connect: express_session_1.default,
124
- }),
125
- });
126
- this.app.use(session);
127
- // setup routes and webserver
128
- await this.initWebUI(session);
129
- return true;
130
- }
131
- // setup the web ui routes
132
- async initWebUI(session) {
133
- this.io = new socket_io_1.Server(this.server);
134
- await this.database.getInstanceId();
135
- // use the session middleware
136
- this.io.use((socket, next) => {
137
- const req = socket.request;
138
- const res = (req.res || {});
139
- session(req, res, async () => {
140
- // check if user is authenticated
141
- const user = await this.database.findUserById(req.session.userId);
142
- if (user && !user.isBanned) {
143
- socket.data.user = user;
144
- await this.database.stores.users.update({ _id: user._id }, { $set: { lastOnline: Date.now() } });
145
- next();
146
- }
147
- else {
148
- next(new Error('unauthorized'));
149
- }
150
- });
151
- });
152
- // provide assets in the /public path
153
- this.app.use('/assets', express_1.default.static(ASSETS_PATH));
154
- this.app.use(body_parser_1.default.json());
155
- this.rooms = ['chat', 'status', 'plugins', 'server'];
156
- // setup the api
157
- (0, api_1.default)(this, this.io);
158
- // setup metrics and tracking
159
- (0, metrics_1.default)(this, this.io);
160
- // every request goes through the index file (frontend handles 404s)
161
- this.app.use(async (req, res) => {
162
- const user = await this.database.findUserById(req.session.userId);
163
- const isAuth = user && !user.isBanned;
164
- if (isAuth) {
165
- res.sendFile(path_1.default.join(PUBLIC_PATH, 'app.html'));
166
- }
167
- else {
168
- res.sendFile(path_1.default.join(PUBLIC_PATH, 'auth.html'));
169
- }
170
- });
171
- }
172
- // start the webserver
173
- async start() {
174
- if (this.started)
175
- return;
176
- await this.created;
177
- return await new Promise(resolve => {
178
- this.server.listen(this.port, () => {
179
- log(`${'>>'.green} Web UI available at`, `http${this.https ? 's' : ''}://127.0.0.1:${this.port}`.green);
180
- this.started = true;
181
- this.database.addChatLog('server', {}, 'Server started');
182
- resolve();
183
- });
184
- });
185
- }
186
- // stop the webserver
187
- stop() {
188
- this.database.addChatLog('server', {}, 'Server stopped');
189
- this.server.close();
190
- this.started = false;
191
- clearInterval(this.serverStatusInterval);
192
- }
23
+ // create a webserver
24
+ constructor(options, omegga) {
25
+ this.port = Number(
26
+ options.port || process.env.OMEGGA_PORT || softconfig.default.DEFAULT_PORT
27
+ );
28
+ this.options = options;
29
+ this.omegga = omegga;
30
+ this.dataPath = path.join(omegga.path, softconfig.default.DATA_PATH);
31
+ this.database = new database.default(options, omegga);
32
+ this.https = false;
33
+ this.started = false;
34
+ this.created = this.createServer();
35
+ }
36
+ // create the webserver
37
+ async createServer() {
38
+ const hasOpenSSL = hasbin.sync("openssl");
39
+ await this.database.doMigrations();
40
+ this.app = express();
41
+ const pickProtocol = async () => {
42
+ if (this.options.https) {
43
+ if (hasOpenSSL) {
44
+ const certFile = await util.getSSLKeys(this.dataPath);
45
+ if (certFile) {
46
+ if (certFile.new) log(">>".green, "Generated new SSL certificate");
47
+ this.https = true;
48
+ return https.createServer(
49
+ {
50
+ key: certFile.keys.serviceKey,
51
+ cert: certFile.keys.certificate
52
+ },
53
+ this.app
54
+ );
55
+ } else {
56
+ error(
57
+ "!>".red,
58
+ "Error generating SSL certificate - falling back to http"
59
+ );
60
+ }
61
+ }
62
+ log(
63
+ ":>".yellow,
64
+ "Running web server with http - install",
65
+ "openssl".yellow.underline,
66
+ "for https (more secure)"
67
+ );
68
+ }
69
+ return new http.Server(this.app);
70
+ };
71
+ this.server = await pickProtocol();
72
+ this.app.set("trust proxy", 1);
73
+ const session = expressSession({
74
+ secret: util.getSessionSecret(this.dataPath),
75
+ resave: false,
76
+ saveUninitialized: false,
77
+ cookie: {
78
+ path: "/",
79
+ secure: this.https,
80
+ maxAge: 365 * 24 * 60 * 60 * 1e3
81
+ // 1 year
82
+ },
83
+ // use a nedb database for session store
84
+ // For some reason vite is not importing the default export properly without this...
85
+ store: NedbStore["default"]({
86
+ filename: path.join(this.dataPath, softconfig.default.SESSION_STORE),
87
+ connect: expressSession
88
+ })
89
+ });
90
+ this.app.use(session);
91
+ await this.initWebUI(session);
92
+ return true;
93
+ }
94
+ // setup the web ui routes
95
+ async initWebUI(session) {
96
+ this.io = new socket_io.Server(this.server);
97
+ await this.database.getInstanceId();
98
+ this.io.use((socket, next) => {
99
+ const req = socket.request;
100
+ const res = req.res || {};
101
+ session(req, res, async () => {
102
+ const user = await this.database.findUserById(
103
+ req.session.userId
104
+ );
105
+ if (user && !user.isBanned) {
106
+ socket.data.user = user;
107
+ await this.database.stores.users.update(
108
+ { _id: user._id },
109
+ { $set: { lastOnline: Date.now() } }
110
+ );
111
+ next();
112
+ } else {
113
+ next(new Error("unauthorized"));
114
+ }
115
+ });
116
+ });
117
+ this.app.use("/assets", express.static(ASSETS_PATH));
118
+ this.app.use(bodyParser.json());
119
+ this.rooms = ["chat", "status", "plugins", "server"];
120
+ api.default(this, this.io);
121
+ metrics.default(this, this.io);
122
+ this.app.use(async (req, res) => {
123
+ const user = await this.database.findUserById(req.session.userId);
124
+ const isAuth = user && !user.isBanned;
125
+ if (isAuth) {
126
+ res.sendFile(path.join(PUBLIC_PATH, "app.html"));
127
+ } else {
128
+ res.sendFile(path.join(PUBLIC_PATH, "auth.html"));
129
+ }
130
+ });
131
+ }
132
+ // start the webserver
133
+ async start() {
134
+ if (this.started) return;
135
+ await this.created;
136
+ return await new Promise((resolve) => {
137
+ this.server.listen(this.port, () => {
138
+ log(
139
+ `${">>".green} Web UI available at`,
140
+ `http${this.https ? "s" : ""}://127.0.0.1:${this.port}`.green
141
+ );
142
+ this.started = true;
143
+ this.database.addChatLog("server", {}, "Server started");
144
+ resolve();
145
+ });
146
+ });
147
+ }
148
+ // stop the webserver
149
+ stop() {
150
+ this.database.addChatLog("server", {}, "Server stopped");
151
+ this.server.close();
152
+ this.started = false;
153
+ clearInterval(this.serverStatusInterval);
154
+ }
193
155
  }
194
156
  exports.default = Webserver;
195
- //# sourceMappingURL=index.js.map
157
+ //# sourceMappingURL=index.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/webserver/backend/index.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"index.js","sources":["../../../src/webserver/backend/index.ts"],"sourcesContent":["import Logger from '@/logger';\nimport soft from '@/softconfig';\nimport { IServerConfig } from '@config/types';\nimport type Omegga from '@omegga/server';\nimport { IServerStatus } from '@omegga/types';\nimport bodyParser from 'body-parser';\nimport express from 'express';\nimport expressSession from 'express-session';\nimport hasbin from 'hasbin';\nimport http from 'http';\nimport https from 'https';\nimport NedbStore from 'nedb-promises-session-store';\nimport path from 'path';\nimport { Server as SocketIo } from 'socket.io';\nimport setupApi from './api';\nimport Database from './database';\nimport setupMetrics from './metrics';\nimport { IStoreUser, OmeggaSocketIo } from './types';\nimport * as util from './util';\n\n// path to vite-built data\nconst PUBLIC_PATH = path.join(__dirname, '../../../public');\nconst ASSETS_PATH = path.join(__dirname, '../../../public/assets');\n\nconst log = (...args: any[]) => Logger.log(...args);\nconst error = (...args: any[]) => Logger.error(...args);\n\n// the webserver servers an authenticated\nexport default class Webserver {\n database: Database;\n port: number;\n omegga: Omegga;\n\n app: express.Express;\n server: http.Server | https.Server;\n io: OmeggaSocketIo;\n\n options: IServerConfig;\n https: boolean;\n started: boolean;\n created: Promise<boolean>;\n\n serverStatusInterval: ReturnType<typeof setInterval>;\n lastReportedStatus: IServerStatus;\n\n rooms: string[];\n\n dataPath: string;\n\n // create a webserver\n constructor(options: IServerConfig, omegga: Omegga) {\n this.port = Number(\n options.port || process.env.OMEGGA_PORT || soft.DEFAULT_PORT,\n );\n this.options = options;\n this.omegga = omegga;\n this.dataPath = path.join(omegga.path, soft.DATA_PATH);\n\n // the database provides omegga with metrics, chat logs, and more\n // to help administrators keep track of their users and server\n this.database = new Database(options, omegga);\n\n // https status of the server\n this.https = false;\n // started status of the server\n this.started = false;\n this.created = this.createServer();\n }\n\n // create the webserver\n async createServer() {\n const hasOpenSSL = hasbin.sync('openssl');\n\n // let the database do migrations\n await this.database.doMigrations();\n\n // create express app\n this.app = express();\n\n // create a server with https if applicable\n const pickProtocol = async () => {\n if (this.options.https) {\n if (hasOpenSSL) {\n const certFile = await util.getSSLKeys(this.dataPath);\n if (certFile) {\n // handy notification of generated ssl certs\n if (certFile.new) log('>>'.green, 'Generated new SSL certificate');\n\n this.https = true;\n return https.createServer(\n {\n key: certFile.keys.serviceKey,\n cert: certFile.keys.certificate,\n },\n this.app,\n );\n } else {\n error(\n '!>'.red,\n 'Error generating SSL certificate - falling back to http',\n );\n }\n }\n\n // warn the user\n log(\n ':>'.yellow,\n 'Running web server with http - install',\n 'openssl'.yellow.underline,\n 'for https (more secure)',\n );\n }\n\n // fallback to http\n return new http.Server(this.app);\n };\n\n // create http(s) server based on openssl availability\n this.server = await pickProtocol();\n\n this.app.set('trust proxy', 1);\n const session = expressSession({\n secret: util.getSessionSecret(this.dataPath),\n resave: false,\n saveUninitialized: false,\n cookie: {\n path: '/',\n secure: this.https,\n maxAge: 365 * 24 * 60 * 60 * 1000, // 1 year\n },\n // use a nedb database for session store\n // For some reason vite is not importing the default export properly without this...\n store: (NedbStore['default'] as typeof NedbStore)({\n filename: path.join(this.dataPath, soft.SESSION_STORE),\n connect: expressSession,\n }),\n });\n this.app.use(session);\n\n // setup routes and webserver\n await this.initWebUI(session);\n return true;\n }\n\n // setup the web ui routes\n async initWebUI(session: ReturnType<typeof expressSession>) {\n this.io = new SocketIo(this.server);\n\n await this.database.getInstanceId();\n\n // use the session middleware\n this.io.use((socket, next) => {\n const req = socket.request as express.Request;\n const res = (req.res || {}) as express.Response<any, { userId: string }>;\n\n session(req, res, async () => {\n // check if user is authenticated\n const user = await this.database.findUserById(\n req.session.userId as string,\n );\n if (user && !user.isBanned) {\n socket.data.user = user;\n await this.database.stores.users.update<IStoreUser>(\n { _id: user._id },\n { $set: { lastOnline: Date.now() } },\n );\n next();\n } else {\n next(new Error('unauthorized'));\n }\n });\n });\n\n // provide assets in the /public path\n this.app.use('/assets', express.static(ASSETS_PATH));\n this.app.use(bodyParser.json());\n\n this.rooms = ['chat', 'status', 'plugins', 'server'];\n\n // setup the api\n setupApi(this, this.io);\n\n // setup metrics and tracking\n setupMetrics(this, this.io);\n\n // every request goes through the index file (frontend handles 404s)\n this.app.use(async (req, res) => {\n const user = await this.database.findUserById(req.session.userId);\n const isAuth = user && !user.isBanned;\n if (isAuth) {\n res.sendFile(path.join(PUBLIC_PATH, 'app.html'));\n } else {\n res.sendFile(path.join(PUBLIC_PATH, 'auth.html'));\n }\n });\n }\n\n // start the webserver\n async start() {\n if (this.started) return;\n await this.created;\n return await new Promise<void>(resolve => {\n this.server.listen(this.port, () => {\n log(\n `${'>>'.green} Web UI available at`,\n `http${this.https ? 's' : ''}://127.0.0.1:${this.port}`.green,\n );\n this.started = true;\n this.database.addChatLog('server', {}, 'Server started');\n resolve();\n });\n });\n }\n\n // stop the webserver\n stop() {\n this.database.addChatLog('server', {}, 'Server stopped');\n this.server.close();\n this.started = false;\n clearInterval(this.serverStatusInterval);\n }\n}\n"],"names":["Logger","soft","Database","util.getSSLKeys","util.getSessionSecret","SocketIo","setupApi","setupMetrics"],"mappings":"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"}