diff --git a/.github/CODEOWNERS b/.github/CODEOWNERS new file mode 100644 index 00000000..b55d76cd --- /dev/null +++ b/.github/CODEOWNERS @@ -0,0 +1,3 @@ +# Nix stuff is owned by Rory& - we& want to be notified if these are changed. +/flake.nix root@rory.gay +/nix-update.sh root@rory.gay \ No newline at end of file diff --git a/.github/workflows/nix-build.yml b/.github/workflows/nix-build.yml new file mode 100644 index 00000000..ae9afa2e --- /dev/null +++ b/.github/workflows/nix-build.yml @@ -0,0 +1,18 @@ +name: Nix build + +on: + push: + pull_request: + +jobs: + build-nix: + runs-on: ubuntu-latest + + steps: + - uses: actions/checkout@v4 + - uses: cachix/install-nix-action@v25 + with: + nix_path: nixpkgs=channel:nixos-unstable + - uses: DeterminateSystems/magic-nix-cache-action@v2 + - run: nix build -L + - run: nix develop --command echo OK diff --git a/.gitignore b/.gitignore index bc780d64..e62c03d6 100644 --- a/.gitignore +++ b/.gitignore @@ -18,4 +18,5 @@ build *.log.ansi *.tmp tmp/ -dump/ \ No newline at end of file +dump/ +result diff --git a/.husky/pre-commit b/.husky/pre-commit index 1bc5a8c6..702231b5 100755 --- a/.husky/pre-commit +++ b/.husky/pre-commit @@ -1,4 +1,28 @@ #!/usr/bin/env sh +#!nix-shell -i "bash" -p bash prefetch-npm-deps jq nodejs nix-output-monitor . "$(dirname -- "$0")/_/husky.sh" -npx -y lint-staged \ No newline at end of file +# Check if nix is available +if [ -x "$(/usr/bin/env which nix-shell 2>/dev/null)" ]; then + # Check if we haven't re-executed ourselves yet + if [ ! "$HOOK_NIX_SHELL" ]; then + echo "Nix is available, updating nix flake..." + export HOOK_NIX_SHELL=1 + nix-shell $0 + exit $? + else + nix flake update + # run ./nix-update.sh if package lock has changed and has no unstaged changes + if [ -n "$(git status --porcelain=v1 2>/dev/null | grep -E '^(MM| M) package-lock.json')" ]; then + echo "package-lock.json has unstaged changes. Skipping update of nix dependencies." + elif [ ! -n "$(git status --porcelain=v1 2>/dev/null | grep -E '^M package-lock.json')" ]; then + echo "package-lock.json has no changes. Skipping update of nix dependencies." + else + ./nix-update.sh || exit $? + fi + fi +else + echo "You do not appear to have nix installed. Skipping update of nix dependencies." +fi + +npx -y lint-staged diff --git a/assets/email_templates/new_login_location.html b/assets/email_templates/new_login_location.html index 8c188def..b8c4a4fb 100644 --- a/assets/email_templates/new_login_location.html +++ b/assets/email_templates/new_login_location.html @@ -1,102 +1,120 @@ - + + + + + + + Verify {instanceName} Login from New Location - - - - - - Verify {instanceName} Login from New Location + + - .ExternalClass { - width: 100%; - } - - - - -
- Branding + Branding -
+
-

+

- Hey {userUsername}, -

-

- It looks like someone tried to log into your {instanceName} - account from a new location. If this is you, follow the link - below to authorize logging in from this location on your - account. If this isn't you, we suggest changing your - password as soon as possible. -

-

- IP Address: {ipAddress} -
- Location: {locationCity}, {locationRegion}, - {locationCountryName} -

-
-
+ Hey {userUsername}, +

+

+ It looks like someone tried to log into your {instanceName} + account from a new location. If this is you, follow the link + below to authorize logging in from this location on your + account. If this isn't you, we suggest changing your + password as soon as possible. +

+

+ IP Address: {ipAddress} +
+ Location: {locationCity}, {locationRegion}, + {locationCountryName} +

+
+ -
-
Verify Login +
+
+
-

- Alternatively, you can directly paste this link into - your browser: -

- {actionUrl} + " + > +

+ Alternatively, you can directly paste this link into + your browser: +

+ {actionUrl} +
-
- - - \ No newline at end of file + + diff --git a/assets/email_templates/password_changed.html b/assets/email_templates/password_changed.html index d0426279..7d368a0a 100644 --- a/assets/email_templates/password_changed.html +++ b/assets/email_templates/password_changed.html @@ -1,4 +1,4 @@ - + @@ -22,7 +22,7 @@ -
+
Branding + + + + + + + Password Reset Request for {instanceName} - - - - - - Password Reset Request for {instanceName} + + - .ExternalClass { - width: 100%; - } - - - - -
- Branding + Branding -
+
-

+

- Hey {userUsername}, -

-

- Your {instanceName} password can be reset by clicking the - button below. If you did not request a new password, please - ignore this email. -

-
-
+ Hey {userUsername}, +

+

+ Your {instanceName} password can be reset by clicking the + button below. If you did not request a new password, please + ignore this email. +

+
+ -
-
-

- Alternatively, you can directly paste this link into - your browser: -

- {actionUrl} + " + >Reset Password +
+
+
+

+ Alternatively, you can directly paste this link into + your browser: +

+ {actionUrl} +
-
- - - \ No newline at end of file + + diff --git a/assets/email_templates/phone_removed.html b/assets/email_templates/phone_removed.html index 7cc552e9..bcbc8f18 100644 --- a/assets/email_templates/phone_removed.html +++ b/assets/email_templates/phone_removed.html @@ -1,4 +1,4 @@ - + @@ -22,7 +22,7 @@ -
+
Branding + @@ -22,7 +22,7 @@ -
+
diff --git a/assets/inline-plugins/.gitkeep b/assets/inline-plugins/.gitkeep deleted file mode 100644 index e69de29b..00000000 diff --git a/assets/locales/de/auth.json b/assets/locales/de/auth.json index e19547a0..f41b67db 100644 --- a/assets/locales/de/auth.json +++ b/assets/locales/de/auth.json @@ -1,16 +1,24 @@ { "login": { - "INVALID_LOGIN": "E-Mail or Phone not found", - "INVALID_PASSWORD": "Invalid Password", - "ACCOUNT_DISABLED": "This account is disabled" + "INVALID_LOGIN": "Ungültiger Benutzername/E-Mail oder Passwort.", + "INVALID_PASSWORD": "Ungültiges Passwort", + "ACCOUNT_DISABLED": "Dieser Account wurde deaktiviert", + "INVALID_TOTP_CODE": "Ungültiger Zwei-Faktor-Authentifierungs-Code.", + "INVALID_TOTP_SECRET": "Ungültiges Zwei-Faktor-Authentifierungs-Secret" }, "register": { - "REGISTRATION_DISABLED": "New user registration is disabled", - "INVITE_ONLY": "You must be invited to register", - "EMAIL_INVALID": "Invalid Email", - "EMAIL_ALREADY_REGISTERED": "Email is already registered", - "DATE_OF_BIRTH_UNDERAGE": "You need to be {{years}} years or older", - "CONSENT_REQUIRED": "You must agree to the Terms of Service and Privacy Policy.", - "USERNAME_TOO_MANY_USERS": "Too many users have this username, please try another" + "REGISTRATION_DISABLED": "Die Registrierung von neuen Benutzern ist deaktiviert", + "INVITE_ONLY": "Du musst eingeladen werden, um dich registrieren zu können", + "EMAIL_INVALID": "Ungültige E-Mail-Adresse", + "EMAIL_ALREADY_REGISTERED": "E-Mail-Adresse ist bereits registriert", + "DATE_OF_BIRTH_UNDERAGE": "Du musst mindestens {{years}} Jahre oder älter sein", + "PASSWORD_REQUIREMENTS_MIN_LENGTH": "Das Passwort muss mindestens {{min}} Zeichen lang sein.", + "CONSENT_REQUIRED": "Du musst den Nutzungsbedingungen und der Datenschutzerklärung zustimmen.", + "USERNAME_TOO_MANY_USERS": "Zu viele Nutzer haben diesen Benutzernamen, bitte probiere einen anderen", + "TOO_MANY_REGISTRATIONS": "Zu viele Registrierungen, bitte versuche es später erneut" + }, + "password_reset": { + "EMAIL_DOES_NOT_EXIST": "E-Mail-Adresse existiert nicht.", + "INVALID_TOKEN": "Ungültiger Token." } } diff --git a/assets/locales/en/auth.json b/assets/locales/en/auth.json index 0521a902..bdc90642 100644 --- a/assets/locales/en/auth.json +++ b/assets/locales/en/auth.json @@ -1,6 +1,6 @@ { "login": { - "INVALID_LOGIN": "E-Mail or Phone not found", + "INVALID_LOGIN": "Invalid login or password.", "INVALID_PASSWORD": "Invalid Password", "ACCOUNT_DISABLED": "This account is disabled", "INVALID_TOTP_CODE": "Invalid two-factor code.", @@ -12,9 +12,9 @@ "EMAIL_INVALID": "Invalid Email", "EMAIL_ALREADY_REGISTERED": "Email is already registered", "DATE_OF_BIRTH_UNDERAGE": "You need to be {{years}} years or older", + "PASSWORD_REQUIREMENTS_MIN_LENGTH": "The password must be at least {{min}} characters long.", "CONSENT_REQUIRED": "You must agree to the Terms of Service and Privacy Policy.", "USERNAME_TOO_MANY_USERS": "Too many users have this username, please try another", - "GUESTS_DISABLED": "Guest users are disabled", "TOO_MANY_REGISTRATIONS": "Too many registrations, please try again later" }, "password_reset": { diff --git a/assets/locales/ur/auth.json b/assets/locales/ur/auth.json index 1dac2474..7f558d01 100644 --- a/assets/locales/ur/auth.json +++ b/assets/locales/ur/auth.json @@ -10,8 +10,8 @@ "EMAIL_INVALID": "Invalid Email", "EMAIL_ALREADY_REGISTERED": "Email is already registered", "DATE_OF_BIRTH_UNDERAGE": "You need to be {{years}} years or older", - "PASSWORD_REQUIREMENTS_MIN_LENGTH": "Must be at least {{min}} characters long.", - "CONSENT_REQUIRED": "You must agree to the Terms of Service and Privacy Policy.", + "PASSWORD_REQUIREMENTS_MIN_LENGTH": "The password must be at least {{min}} characters long.", + "CONSENT_REQUIRED": "You must agree to the Terms of Service and Privacy Policy.", "USERNAME_TOO_MANY_USERS": "Too many users have this username, please try another" } } diff --git a/assets/openapi.json b/assets/openapi.json index 6860c21b..9bcb54a5 100644 Binary files a/assets/openapi.json and b/assets/openapi.json differ diff --git a/assets/plugins/.gitkeep b/assets/plugins/.gitkeep deleted file mode 100644 index e69de29b..00000000 diff --git a/assets/preload-plugins/.gitkeep b/assets/preload-plugins/.gitkeep deleted file mode 100644 index e69de29b..00000000 diff --git a/assets/preload-plugins/checkLocale.js b/assets/preload-plugins/checkLocale.js deleted file mode 100644 index 1b5e7b71..00000000 --- a/assets/preload-plugins/checkLocale.js +++ /dev/null @@ -1,38 +0,0 @@ -const supportedLocales = [ - "bg", - "cs", - "da", - "de", - "el", - "en-GB", - "es-ES", - "fi", - "fr", - "hi", - "hr", - "hu", - "it", - "ja", - "ko", - "lt", - "nl", - "no", - "pl", - "pt-BR", - "ro", - "ru", - "sv-SE", - "th", - "tr", - "uk", - "vi", - "zh-CN", - "zh-TW" -]; - -const settings = JSON.parse(window.localStorage.getItem("UserSettingsStore")); -if (settings && !supportedLocales.includes(settings.locale)) { - // fix client locale wrong and client not loading at all - settings.locale = "en-US"; - window.localStorage.setItem("UserSettingsStore", JSON.stringify(settings)); -} \ No newline at end of file diff --git a/assets/preload-plugins/oauth2.js b/assets/preload-plugins/oauth2.js deleted file mode 100644 index 5b78ec83..00000000 --- a/assets/preload-plugins/oauth2.js +++ /dev/null @@ -1,9 +0,0 @@ -// Fixes /oauth2 endpoints not requesting a CSS file - -if (location.pathname.startsWith("/oauth2/")) { - const link = document.createElement("link"); - link.rel = "stylesheet" - link.type = "text/css" - link.href = "/assets/40532.f7b1e10347ef10e790ac.css" - document.head.appendChild(link) -} \ No newline at end of file diff --git a/assets/public/0c8138dcc0dfe2689cdd73f7952c2475.png b/assets/public/0c8138dcc0dfe2689cdd73f7952c2475.png deleted file mode 100644 index 3e8eeae9..00000000 Binary files a/assets/public/0c8138dcc0dfe2689cdd73f7952c2475.png and /dev/null differ diff --git a/assets/public/22341bdb500c7b63a93bbce957d1601e.png b/assets/public/22341bdb500c7b63a93bbce957d1601e.png new file mode 100644 index 00000000..c8bf93d0 Binary files /dev/null and b/assets/public/22341bdb500c7b63a93bbce957d1601e.png differ diff --git a/assets/public/4a8562cf00887030c416d3ec2d46385a.png b/assets/public/4a8562cf00887030c416d3ec2d46385a.png new file mode 100644 index 00000000..73426bcd Binary files /dev/null and b/assets/public/4a8562cf00887030c416d3ec2d46385a.png differ diff --git a/assets/public/5ac2728593bb455250d11b848a0c36c6.png b/assets/public/5ac2728593bb455250d11b848a0c36c6.png deleted file mode 100644 index 9f137906..00000000 Binary files a/assets/public/5ac2728593bb455250d11b848a0c36c6.png and /dev/null differ diff --git a/assets/public/7213ab6677377974697dfdfbaf5f6a6f.png b/assets/public/7213ab6677377974697dfdfbaf5f6a6f.png new file mode 100644 index 00000000..f1fa9f0b Binary files /dev/null and b/assets/public/7213ab6677377974697dfdfbaf5f6a6f.png differ diff --git a/assets/public/823a3de61c4dc2415cc4dbc38fca4299.png b/assets/public/823a3de61c4dc2415cc4dbc38fca4299.png deleted file mode 100644 index 9b92bd2f..00000000 Binary files a/assets/public/823a3de61c4dc2415cc4dbc38fca4299.png and /dev/null differ diff --git a/assets/public/9b0bb198936784c45c72833cc426cc55.png b/assets/public/9b0bb198936784c45c72833cc426cc55.png new file mode 100644 index 00000000..367051ce Binary files /dev/null and b/assets/public/9b0bb198936784c45c72833cc426cc55.png differ diff --git a/assets/public/9d6ddb4e4d899a533a8cc617011351c9.png b/assets/public/9d6ddb4e4d899a533a8cc617011351c9.png new file mode 100644 index 00000000..740cdd25 Binary files /dev/null and b/assets/public/9d6ddb4e4d899a533a8cc617011351c9.png differ diff --git a/assets/public/addd2f3268df46459e1d6012ad8e75bd.png b/assets/public/addd2f3268df46459e1d6012ad8e75bd.png deleted file mode 100644 index 62c599a7..00000000 Binary files a/assets/public/addd2f3268df46459e1d6012ad8e75bd.png and /dev/null differ diff --git a/assets/public/c4e0c8300fa491d94acfd2a1fb26cea8.png b/assets/public/c4e0c8300fa491d94acfd2a1fb26cea8.png deleted file mode 100644 index bd7afef2..00000000 Binary files a/assets/public/c4e0c8300fa491d94acfd2a1fb26cea8.png and /dev/null differ diff --git a/assets/public/d9977836b82058bf2f74eebd50edc095.png b/assets/public/d9977836b82058bf2f74eebd50edc095.png new file mode 100644 index 00000000..bb73cd99 Binary files /dev/null and b/assets/public/d9977836b82058bf2f74eebd50edc095.png differ diff --git a/assets/public/e56a89224be0b2b1f7c04eca975be468.png b/assets/public/e56a89224be0b2b1f7c04eca975be468.png deleted file mode 100644 index 67ee7bbd..00000000 Binary files a/assets/public/e56a89224be0b2b1f7c04eca975be468.png and /dev/null differ diff --git a/assets/public/fosscord-login.css b/assets/public/fosscord-login.css deleted file mode 100644 index e66e70a0..00000000 --- a/assets/public/fosscord-login.css +++ /dev/null @@ -1,68 +0,0 @@ -/* replace tos acceptance popup */ -#app-mount > div:nth-child(7) > div > div > div.tooltipContent-bqVLWK { - visibility: hidden; -} -#app-mount > div:nth-child(7) > div > div > div.tooltipContent-bqVLWK::after { - visibility: visible; - display: block; - content: "You need to agree to this instance's rules to continue"; - margin-top: -32px; -} -/* replace login header */ -#app-mount > div.app-1q1i1E > div > div > div > div > form > div > div > div.mainLoginContainer-1ddwnR > h3 { - visibility: hidden; -} -h3.title-jXR8lp.marginBottom8-AtZOdT.base-1x0h_U.size24-RIRrxO::after { - margin-top: -32px; - content: "Welcome to Spacebar!"; - visibility: visible; - display: block; -} - -/* Logo in top left when bg removed */ -#app-mount > div.app-1q1i1E > div > a { - /* replace me: original dimensions: 130x36 */ - background: url(https://raw.githubusercontent.com/spacebarchat/spacebarchat/master/branding/svg/Spacebar__Logo-Blue.svg); - width: 130px; - height: 23px; - background-size: contain; -} - -/* replace TOS text */ - -#app-mount - > div.app-1q1i1E - > div - > div - > div - > form - > div - > div - > div.flex-1xMQg5.flex-1O1GKY.horizontal-1ae9ci.horizontal-2EEEnY.flex-1O1GKY.directionRow-3v3tfG.justifyStart-2NDFzi.alignCenter-1dQNNs.noWrap-3jynv6.marginTop20-3TxNs6 - > label - > div.label-cywgfr.labelClickable-11AuB8.labelForward-1wfipV - > * { - visibility: hidden; -} - -#app-mount - > div.app-1q1i1E - > div - > div - > div - > form - > div - > div - > div.flex-1xMQg5.flex-1O1GKY.horizontal-1ae9ci.horizontal-2EEEnY.flex-1O1GKY.directionRow-3v3tfG.justifyStart-2NDFzi.alignCenter-1dQNNs.noWrap-3jynv6.marginTop20-3TxNs6 - > label - > div.label-cywgfr.labelClickable-11AuB8.labelForward-1wfipV::after { - visibility: visible; - content: "I have read and agree with the rules set by this instance."; - display: block; - margin-top: -16px; -} - -/* shrink login box to same size as register */ -.authBoxExpanded-2jqaBe { - width: 480px !important; -} \ No newline at end of file diff --git a/assets/public/fosscord.css b/assets/public/fosscord.css deleted file mode 100644 index 53ffd41b..00000000 --- a/assets/public/fosscord.css +++ /dev/null @@ -1,92 +0,0 @@ -/* loading spinner */ -#app-mount > div.app-1q1i1E > div.container-16j22k.fixClipping-3qAKRb > div.content-1-zrf2 > video { - filter: opacity(1); - background: url("http://www.clipartbest.com/cliparts/7ca/6Rr/7ca6RrLAi.gif"); - background-size: contain; - /* width: 64px; - height: 64px; */ - padding-bottom: 64px; - background-repeat: no-repeat; -} - -/* home button icon */ -#app-mount - > div.app-1q1i1E - > div - > div.layers-3iHuyZ.layers-3q14ss - > div - > div - > nav - > ul - > div.scroller-1Bvpku.none-2Eo-qx.scrollerBase-289Jih - > div.tutorialContainer-2sGCg9 - > div - > div.listItemWrapper-KhRmzM - > div - > svg - > foreignObject - > div - > div { - background-image: url(https://raw.githubusercontent.com/spacebarchat/spacebarchat/master/branding/svg/Spacebar__Icon-Rounded-Subtract.svg); - background-size: contain; - border-radius: 50%; -} - -#app-mount - > div.app-1q1i1E - > div - > div.layers-3iHuyZ.layers-3q14ss - > div - > div - > nav - > ul - > div.scroller-1Bvpku.none-2Eo-qx.scrollerBase-289Jih - > div.tutorialContainer-2sGCg9 - > div - > div.listItemWrapper-KhRmzM - > div - > svg - > foreignObject - > div - > div, -#app-mount - > div.app-1q1i1E - > div - > div.layers-3iHuyZ.layers-3q14ss - > div - > div - > nav - > ul - > div.scroller-1Bvpku.none-2Eo-qx.scrollerBase-289Jih - > div.tutorialContainer-2sGCg9 - > div - > div.listItemWrapper-KhRmzM - > div - > svg - > foreignObject - > div - > div:hover { - background-color: white; -} -/* Login QR */ -#app-mount > div.app-1q1i1E > div > div > div > div > form > div > div > div.transitionGroup-aR7y1d.qrLogin-1AOZMt, -#app-mount > div.app-1q1i1E > div > div > div > div > form > div > div > div.verticalSeparator-3huAjp, -/* Remove login bg */ -#app-mount > div.app-1q1i1E > div > svg, -/* Download bar */ -#app-mount > div.app-1q1i1E > div > div.layers-3iHuyZ.layers-3q14ss > div > div > div > div.notice-3bPHh-.colorDefault-22HBa0, -/* Connection problem links */ -#app-mount > div.app-1q1i1E > div.container-16j22k.fixClipping-3qAKRb > div.problems-3mgf6w.slideIn-sCvzGz > div:nth-child(2), -/* Downloads button */ -#app-mount > div.app-1q1i1E > div > div.layers-3iHuyZ.layers-3q14ss > div > div > nav > ul > div.scroller-1Bvpku.none-2Eo-qx.scrollerBase-289Jih > div:nth-child(7) > div.listItemWrapper-KhRmzM > div > svg > foreignObject > div, -#app-mount > div.app-1q1i1E > div > div.layers-3iHuyZ.layers-3q14ss > div > div > nav > ul > div.scroller-1Bvpku.none-2Eo-qx.scrollerBase-289Jih > div:nth-child(6) > div, -/* help button */ -#app-mount > div.app-1q1i1E > div > div.layers-3iHuyZ.layers-3q14ss > div > div > div > div.content-98HsJk > div.chat-3bRxxu > section > div.toolbar-1t6TWx > a, -/* download button start of guild */ -#chat-messages-899316648933185083 > div > div > div:nth-child(5), -/* Thread permissions etc popups */ -#app-mount > div.app-1q1i1E > div > div.layers-3iHuyZ.layers-3q14ss > div > div > div > div.content-98HsJk > div.sidebar-2K8pFh.hasNotice-1XRy4h > nav > div.container-3O_wAf, -/* home button icon */ -#app-mount > div.app-1q1i1E > div > div.layers-3iHuyZ.layers-3q14ss > div > div > nav > ul > div.scroller-1Bvpku.none-2Eo-qx.scrollerBase-289Jih > div.tutorialContainer-2sGCg9 > div > div.listItemWrapper-KhRmzM > div > svg > foreignObject > div > div > svg { - display: none; -} \ No newline at end of file diff --git a/assets/public/user.css b/assets/public/user.css deleted file mode 100644 index a7e5c4f3..00000000 --- a/assets/public/user.css +++ /dev/null @@ -1 +0,0 @@ -/* Your custom CSS goes here, enjoy! */ \ No newline at end of file diff --git a/assets/public/verify.html b/assets/public/verify.html new file mode 100644 index 00000000..c70d7709 --- /dev/null +++ b/assets/public/verify.html @@ -0,0 +1,147 @@ + + + + + + + Spacebar Server + + + + + + + + + +
+ Spacebar Logo + +
+

Verifying your email

+

Please wait...

+
+
+ + + + diff --git a/assets/schemas.json b/assets/schemas.json index 39961d30..bfc7550c 100644 Binary files a/assets/schemas.json and b/assets/schemas.json differ diff --git a/assets/webrtc.js b/assets/webrtc.js deleted file mode 100644 index b56e41c4..00000000 --- a/assets/webrtc.js +++ /dev/null @@ -1,82 +0,0 @@ -/* - This file is used to patch client version 134842 ( and probably a lot more ) to send additional info when using webrtc. - If you want to use it, throw it into the `preload-plugins` folder. - TODO: Make it so this file is not required for webrtc. - - Do note that webrtc, as of 17/12/2022, is not implemented yet in spacebarchat/server. -*/ - -(this.webpackChunkdiscord_app = this.webpackChunkdiscord_app || []).push([ - [[228974]], - { - 632540: (module, exports, req) => { - window.find = (filter, options = {}) => { - const { cacheOnly = false } = options; - for (let i in req.c) { - if (req.c.hasOwnProperty(i)) { - let m = req.c[i].exports; - if (m && m.__esModule && m.default && filter(m.default)) return m.default; - if (m && filter(m)) return m; - } - } - if (cacheOnly) { - console.warn("Cannot find loaded module in cache"); - return null; - } - console.warn("Cannot find loaded module in cache. Loading all modules may have unexpected side effects"); - for (let i = 0; i < req.m.length; ++i) { - let m = req(i); - if (m && m.__esModule && m.default && filter(m.default)) return m.default; - if (m && filter(m)) return m; - } - console.warn("Cannot find module"); - return null; - }; - window.findByUniqueProperties = (propNames, options) => - find((module) => propNames.every((prop) => module[prop] !== undefined), options); - window.findByDisplayName = (displayName, options) => find((module) => module.displayName === displayName, options); - window.req = req; - - init(); - } - }, - (t) => t(632540) -]); - -function retry(callback) { - return new Promise((resolve) => { - const interval = setInterval(() => { - const mod = callback(); - if (!mod) return; - - clearInterval(interval); - resolve(mod); - }, 50); - }); -} - -async function init() { - const SDP = await retry(() => findByUniqueProperties(["truncateSDP"])); - const StringManipulator = findByUniqueProperties(["uniq"]); - - const truncateSDP = SDP.truncateSDP; - SDP.truncateSDP = (e) => { - const result = truncateSDP(e); - const i = result.codecs.find((x) => x.name === "VP8"); - const a = new RegExp("^a=ice|a=extmap|opus|VP8|fingerprint|" + i?.rtxPayloadType + " rtx", "i"); - return { - sdp: StringManipulator(e) - .split(/\r\n/) - .filter(function (e) { - return a.test(e); - }) - .uniq() - .join("\n"), - codecs: result.codecs - }; - }; - // SDP.generateUnifiedSessionDescription = (e) => { - // console.log(e); - // return new RTCSessionDescription({ sdp: e.baseSDP.replace(/sendonly/g, "recvonly"), type: "answer" }); - // }; -} \ No newline at end of file diff --git a/flake.lock b/flake.lock new file mode 100644 index 00000000..844f26fa Binary files /dev/null and b/flake.lock differ diff --git a/flake.nix b/flake.nix new file mode 100644 index 00000000..00a18f64 --- /dev/null +++ b/flake.nix @@ -0,0 +1,70 @@ +{ + description = "Spacebar server, written in Typescript."; + + inputs = { + nixpkgs.url = "github:nixos/nixpkgs/nixos-unstable"; + flake-utils.url = "github:numtide/flake-utils"; + }; + + outputs = { self, nixpkgs, flake-utils }: + flake-utils.lib.eachSystem flake-utils.lib.allSystems (system: + let + pkgs = import nixpkgs { + inherit system; + }; + hashesFile = builtins.fromJSON (builtins.readFile ./hashes.json); + in rec { + packages.default = pkgs.buildNpmPackage { + pname = "spacebar-server-ts"; + src = ./.; + name = "spacebar-server-ts"; + nativeBuildInputs = with pkgs; [ python3 ]; + npmDepsHash = hashesFile.npmDepsHash; + makeCacheWritable = true; + postPatch = '' + substituteInPlace package.json --replace 'npx patch-package' '${pkgs.nodePackages.patch-package}/bin/patch-package' + ''; + installPhase = '' + runHook preInstall + set -x + #remove packages not needed for production, or at least try to... + npm prune --omit dev --no-save $npmInstallFlags "''${npmInstallFlagsArray[@]}" $npmFlags "''${npmFlagsArray[@]}" + find node_modules -maxdepth 1 -type d -empty -delete + + mkdir -p $out/node_modules/ + cp -r node_modules/* $out/node_modules/ + cp -r dist/ $out/node_modules/@spacebar + for i in dist/**/start.js + do + makeWrapper ${pkgs.nodejs-slim}/bin/node $out/bin/start-`dirname ''${i/dist\//}` --prefix NODE_PATH : $out/node_modules --add-flags $out/node_modules/@spacebar`dirname ''${i/dist/}`/start.js + done + set +x + substituteInPlace package.json --replace 'dist/' 'node_modules/@spacebar/' + find $out/node_modules/@spacebar/ -type f -name "*.js" | while read srcFile; do + echo Patching imports in ''${srcFile/$out\/node_modules\/@spacebar//}... + substituteInPlace $srcFile --replace 'require("./' 'require(__dirname + "/' + substituteInPlace $srcFile --replace 'require("../' 'require(__dirname + "/../' + substituteInPlace $srcFile --replace ', "assets"' ', "..", "assets"' + #substituteInPlace $srcFile --replace 'require("@spacebar/' 'require(" + done + set -x + cp -r assets/ $out/ + cp package.json $out/ + rm -v $out/assets/openapi.json + #rm -v $out/assets/schemas.json + + #debug utils: + #cp $out/node_modules/@spacebar/ $out/build_output -r + set +x + runHook postInstall + ''; + }; + devShell = pkgs.mkShell { + buildInputs = with pkgs; [ + nodejs + nodePackages.typescript + ]; + }; + } + ); +} diff --git a/hashes.json b/hashes.json new file mode 100644 index 00000000..dd55b81d --- /dev/null +++ b/hashes.json @@ -0,0 +1,3 @@ +{ + "npmDepsHash": "sha256-fZNDN2/fNy6Nu7tbr0RhQ8j4BP7X1Yhrh/fSTH7hbJc=" +} diff --git a/nix-update.sh b/nix-update.sh new file mode 100755 index 00000000..4413e6e0 --- /dev/null +++ b/nix-update.sh @@ -0,0 +1,10 @@ +#!/usr/bin/env nix-shell +#!nix-shell -i "bash -x" -p bash prefetch-npm-deps jq git nix-output-monitor +nix flake update +DEPS_HASH=`prefetch-npm-deps package-lock.json` +TMPFILE=$(mktemp) +jq '.npm_deps_hash = "'$DEPS_HASH'"' hashes.json > $TMPFILE +mv -- "$TMPFILE" hashes.json + +nom build .# || exit $? +git add hashes.json flake.lock flake.nix \ No newline at end of file diff --git a/package-lock.json b/package-lock.json index aabad644..875aba1b 100644 Binary files a/package-lock.json and b/package-lock.json differ diff --git a/package.json b/package.json index 3994670b..ac42c767 100644 --- a/package.json +++ b/package.json @@ -10,6 +10,7 @@ "start:cdn": "node dist/cdn/start.js", "start:gateway": "node dist/gateway/start.js", "build": "tsc -p .", + "watch": "tsc -w -p .", "test": "node scripts/test.js", "lint": "eslint .", "setup": "npm run build && npm run generate:schema", @@ -55,9 +56,9 @@ "@types/probe-image-size": "^7.2.0", "@types/sharp": "^0.31.1", "@types/ws": "^8.5.5", - "@typescript-eslint/eslint-plugin": "^5.62.0", - "@typescript-eslint/parser": "^5.62.0", - "eslint": "^8.46.0", + "@typescript-eslint/eslint-plugin": "^6.21.0", + "@typescript-eslint/parser": "^6.21.0", + "eslint": "^8.56.0", "express": "^4.18.2", "husky": "^8.0.3", "prettier": "^2.8.8", @@ -116,9 +117,11 @@ }, "optionalDependencies": { "erlpack": "^0.1.4", + "mysql": "^2.18.1", "nodemailer-mailgun-transport": "^2.1.5", "nodemailer-mailjet-transport": "github:n0script22/nodemailer-mailjet-transport", "nodemailer-sendgrid-transport": "github:Maria-Golomb/nodemailer-sendgrid-transport", + "pg": "^8.11.3", "sqlite3": "^5.1.6" } } diff --git a/src/api/Server.ts b/src/api/Server.ts index 472ab1d6..40d2b6dc 100644 --- a/src/api/Server.ts +++ b/src/api/Server.ts @@ -18,15 +18,15 @@ import { Config, - Email, - initDatabase, - initEvent, - JSONReplacer, - registerRoutes, - Sentry, - WebAuthn, ConnectionConfig, ConnectionLoader, + Email, + JSONReplacer, + Sentry, + WebAuthn, + initDatabase, + initEvent, + registerRoutes, } from "@spacebar/util"; import { Request, Response, Router } from "express"; import { Server, ServerOptions } from "lambert-server"; @@ -141,6 +141,10 @@ export class SpacebarServer extends Server { res.sendFile(path.join(PUBLIC_ASSETS_FOLDER, "index.html")), ); + app.get("/verify", (req, res) => + res.sendFile(path.join(PUBLIC_ASSETS_FOLDER, "verify.html")), + ); + this.app.use(ErrorHandler); Sentry.errorHandler(this.app); diff --git a/src/api/routes/applications/#id/index.ts b/src/api/routes/applications/#id/index.ts index c372869a..949d66f8 100644 --- a/src/api/routes/applications/#id/index.ts +++ b/src/api/routes/applications/#id/index.ts @@ -21,6 +21,7 @@ import { Application, ApplicationModifySchema, DiscordApiErrors, + handleFile, } from "@spacebar/util"; import { Request, Response, Router } from "express"; import { HTTPError } from "lambert-server"; @@ -83,6 +84,13 @@ router.patch( ) throw new HTTPError(req.t("auth:login.INVALID_TOTP_CODE"), 60008); + if (body.icon) { + body.icon = await handleFile( + `/app-icons/${app.id}`, + body.icon as string, + ); + } + if (app.bot) { app.bot.assign({ bio: body.description }); await app.bot.save(); diff --git a/src/api/routes/auth/generate-registration-tokens.ts b/src/api/routes/auth/generate-registration-tokens.ts index 80fdaed1..50c389e0 100644 --- a/src/api/routes/auth/generate-registration-tokens.ts +++ b/src/api/routes/auth/generate-registration-tokens.ts @@ -38,7 +38,7 @@ router.get( "The length of each registration token. Defaults to 255.", }, }, - right: "OPERATOR", + right: "CREATE_REGISTRATION_TOKENS", responses: { 200: { body: "GenerateRegistrationTokensResponse" } }, }), async (req: Request, res: Response) => { diff --git a/src/api/routes/auth/verify/index.ts b/src/api/routes/auth/verify/index.ts index 49f74277..32c3f305 100644 --- a/src/api/routes/auth/verify/index.ts +++ b/src/api/routes/auth/verify/index.ts @@ -85,7 +85,7 @@ router.post( user = userTokenData.user; } catch { throw FieldErrors({ - password: { + token: { message: req.t("auth:password_reset.INVALID_TOKEN"), code: "INVALID_TOKEN", }, diff --git a/src/api/routes/channels/#channel_id/index.ts b/src/api/routes/channels/#channel_id/index.ts index 567c7c92..291b6472 100644 --- a/src/api/routes/channels/#channel_id/index.ts +++ b/src/api/routes/channels/#channel_id/index.ts @@ -1,17 +1,17 @@ /* Spacebar: A FOSS re-implementation and extension of the Discord.com backend. Copyright (C) 2023 Spacebar and Spacebar 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 . */ @@ -50,7 +50,13 @@ router.get( const channel = await Channel.findOneOrFail({ where: { id: channel_id }, }); + if (!channel.guild_id) return res.send(channel); + channel.position = await Channel.calculatePosition( + channel_id, + channel.guild_id, + channel.guild, + ); return res.send(channel); }, ); @@ -90,6 +96,24 @@ router.delete( } else if (channel.type === ChannelType.GROUP_DM) { await Channel.removeRecipientFromChannel(channel, req.user_id); } else { + if (channel.type == ChannelType.GUILD_CATEGORY) { + const channels = await Channel.find({ + where: { parent_id: channel_id }, + }); + for await (const c of channels) { + c.parent_id = null; + + await Promise.all([ + c.save(), + emitEvent({ + event: "CHANNEL_UPDATE", + data: c, + channel_id: c.id, + } as ChannelUpdateEvent), + ]); + } + } + await Promise.all([ Channel.delete({ id: channel_id }), emitEvent({ diff --git a/src/api/routes/channels/#channel_id/messages/#message_id/crosspost.ts b/src/api/routes/channels/#channel_id/messages/#message_id/crosspost.ts index 5ca645c0..6362941c 100644 --- a/src/api/routes/channels/#channel_id/messages/#message_id/crosspost.ts +++ b/src/api/routes/channels/#channel_id/messages/#message_id/crosspost.ts @@ -1,17 +1,17 @@ /* Spacebar: A FOSS re-implementation and extension of the Discord.com backend. Copyright (C) 2023 Spacebar and Spacebar 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 . */ @@ -56,6 +56,7 @@ router.post( edited_timestamp: null, flags: 1, components: [], + poll: {}, }).status(200); }, ); diff --git a/src/api/routes/channels/#channel_id/messages/#message_id/index.ts b/src/api/routes/channels/#channel_id/messages/#message_id/index.ts index c4d2e1e8..211cf997 100644 --- a/src/api/routes/channels/#channel_id/messages/#message_id/index.ts +++ b/src/api/routes/channels/#channel_id/messages/#message_id/index.ts @@ -1,17 +1,17 @@ /* Spacebar: A FOSS re-implementation and extension of the Discord.com backend. Copyright (C) 2023 Spacebar and Spacebar 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 . */ @@ -91,11 +91,10 @@ router.patch( } } else rights.hasThrow("SELF_EDIT_MESSAGES"); + // @ts-expect-error Something is wrong with message_reference here, TS complains since "channel_id" is optional in MessageCreateSchema const new_message = await handleMessage({ ...message, // TODO: should message_reference be overridable? - // eslint-disable-next-line @typescript-eslint/ban-ts-comment - // @ts-ignore message_reference: message.message_reference, ...body, author_id: message.author_id, diff --git a/src/api/routes/channels/#channel_id/messages/index.ts b/src/api/routes/channels/#channel_id/messages/index.ts index a5bfcfd7..645c6db2 100644 --- a/src/api/routes/channels/#channel_id/messages/index.ts +++ b/src/api/routes/channels/#channel_id/messages/index.ts @@ -1,17 +1,17 @@ /* Spacebar: A FOSS re-implementation and extension of the Discord.com backend. Copyright (C) 2023 Spacebar and Spacebar 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 . */ @@ -183,9 +183,17 @@ router.get( const uri = y.proxy_url.startsWith("http") ? y.proxy_url : `https://example.org${y.proxy_url}`; - y.proxy_url = `${endpoint == null ? "" : endpoint}${ - new URL(uri).pathname - }`; + + let pathname = new URL(uri).pathname; + while ( + pathname.split("/")[0] != "attachments" && + pathname.length > 30 + ) { + pathname = pathname.split("/").slice(1).join("/"); + } + if (!endpoint?.endsWith("/")) pathname = "/" + pathname; + + y.proxy_url = `${endpoint == null ? "" : endpoint}${pathname}`; }); /** diff --git a/src/api/routes/channels/#channel_id/permissions.ts b/src/api/routes/channels/#channel_id/permissions.ts index d3edb0fa..fe289f23 100644 --- a/src/api/routes/channels/#channel_id/permissions.ts +++ b/src/api/routes/channels/#channel_id/permissions.ts @@ -1,17 +1,17 @@ /* Spacebar: A FOSS re-implementation and extension of the Discord.com backend. Copyright (C) 2023 Spacebar and Spacebar 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 . */ @@ -53,6 +53,11 @@ router.put( where: { id: channel_id }, }); if (!channel.guild_id) throw new HTTPError("Channel not found", 404); + channel.position = await Channel.calculatePosition( + channel_id, + channel.guild_id, + channel.guild, + ); if (body.type === 0) { if (!(await Role.count({ where: { id: overwrite_id } }))) diff --git a/src/api/routes/connections/index.ts b/src/api/routes/connections/index.ts new file mode 100644 index 00000000..37c20a37 --- /dev/null +++ b/src/api/routes/connections/index.ts @@ -0,0 +1,45 @@ +/* + Spacebar: A FOSS re-implementation and extension of the Discord.com backend. + Copyright (C) 2023 Spacebar and Spacebar 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 . +*/ + +import { route } from "@spacebar/api"; +import { ConnectionConfig } from "@spacebar/util"; +import { Request, Response, Router } from "express"; +const router = Router(); + +router.get( + "/", + route({ + responses: { + 200: { + body: "APIConnectionsConfiguration", + }, + }, + }), + async (req: Request, res: Response) => { + const config = ConnectionConfig.get(); + + Object.keys(config).forEach((key) => { + delete config[key].clientId; + delete config[key].clientSecret; + }); + + res.json(config); + }, +); + +export default router; diff --git a/src/api/routes/guilds/#guild_id/bans.ts b/src/api/routes/guilds/#guild_id/bans.ts index 0776ab62..5ae9bdb9 100644 --- a/src/api/routes/guilds/#guild_id/bans.ts +++ b/src/api/routes/guilds/#guild_id/bans.ts @@ -1,17 +1,17 @@ /* Spacebar: A FOSS re-implementation and extension of the Discord.com backend. Copyright (C) 2023 Spacebar and Spacebar 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 . */ @@ -19,7 +19,6 @@ import { getIpAdress, route } from "@spacebar/api"; import { Ban, - BanModeratorSchema, BanRegistrySchema, DiscordApiErrors, GuildBanAddEvent, @@ -82,7 +81,7 @@ router.get( ); router.get( - "/:user", + "/:user_id", route({ permission: "BAN_MEMBERS", responses: { @@ -98,23 +97,21 @@ router.get( }, }), async (req: Request, res: Response) => { - const { guild_id } = req.params; - const user_id = req.params.ban; + const { guild_id, user_id } = req.params; - let ban = (await Ban.findOneOrFail({ + const ban = (await Ban.findOneOrFail({ where: { guild_id: guild_id, user_id: user_id }, })) as BanRegistrySchema; if (ban.user_id === ban.executor_id) throw DiscordApiErrors.UNKNOWN_BAN; // pretend self-bans don't exist to prevent victim chasing - /* Filter secret from registry. */ + const banInfo = { + user: await User.getPublicUser(ban.user_id), + reason: ban.reason, + }; - ban = ban as BanModeratorSchema; - - delete ban.ip; - - return res.json(ban); + return res.json(banInfo); }, ); @@ -151,6 +148,12 @@ router.put( if (req.permission?.cache.guild?.owner_id === banned_user_id) throw new HTTPError("You can't ban the owner", 400); + const existingBan = await Ban.findOne({ + where: { guild_id: guild_id, user_id: banned_user_id }, + }); + // Bans on already banned users are silently ignored + if (existingBan) return res.status(204).send(); + const banned_user = await User.getPublicUser(banned_user_id); const ban = Ban.create({ @@ -174,59 +177,7 @@ router.put( } as GuildBanAddEvent), ]); - return res.json(ban); - }, -); - -router.put( - "/@me", - route({ - requestBody: "BanCreateSchema", - responses: { - 200: { - body: "Ban", - }, - 400: { - body: "APIErrorResponse", - }, - 403: { - body: "APIErrorResponse", - }, - }, - }), - async (req: Request, res: Response) => { - const { guild_id } = req.params; - - const banned_user = await User.getPublicUser(req.params.user_id); - - if (req.permission?.cache.guild?.owner_id === req.params.user_id) - throw new HTTPError( - "You are the guild owner, hence can't ban yourself", - 403, - ); - - const ban = Ban.create({ - user_id: req.params.user_id, - guild_id: guild_id, - ip: getIpAdress(req), - executor_id: req.params.user_id, - reason: req.body.reason, // || otherwise empty - }); - - await Promise.all([ - Member.removeFromGuild(req.user_id, guild_id), - ban.save(), - emitEvent({ - event: "GUILD_BAN_ADD", - data: { - guild_id: guild_id, - user: banned_user, - }, - guild_id: guild_id, - } as GuildBanAddEvent), - ]); - - return res.json(ban); + return res.status(204).send(); }, ); @@ -247,13 +198,10 @@ router.delete( async (req: Request, res: Response) => { const { guild_id, user_id } = req.params; - const ban = await Ban.findOneOrFail({ + await Ban.findOneOrFail({ where: { guild_id: guild_id, user_id: user_id }, }); - if (ban.user_id === ban.executor_id) throw DiscordApiErrors.UNKNOWN_BAN; - // make self-bans irreversible and hide them from view to avoid victim chasing - const banned_user = await User.getPublicUser(user_id); await Promise.all([ diff --git a/src/api/routes/guilds/#guild_id/bulk-ban.ts b/src/api/routes/guilds/#guild_id/bulk-ban.ts new file mode 100644 index 00000000..f544103a --- /dev/null +++ b/src/api/routes/guilds/#guild_id/bulk-ban.ts @@ -0,0 +1,130 @@ +/* + Spacebar: A FOSS re-implementation and extension of the Discord.com backend. + Copyright (C) 2023 Spacebar and Spacebar 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 . +*/ + +import { getIpAdress, route } from "@spacebar/api"; +import { + Ban, + DiscordApiErrors, + GuildBanAddEvent, + Member, + User, + emitEvent, +} from "@spacebar/util"; +import { Request, Response, Router } from "express"; +import { HTTPError } from "lambert-server"; + +const router: Router = Router(); + +router.post( + "/", + route({ + requestBody: "BulkBanSchema", + permission: ["BAN_MEMBERS", "MANAGE_GUILD"], + responses: { + 200: { + body: "Ban", + }, + 400: { + body: "APIErrorResponse", + }, + 403: { + body: "APIErrorResponse", + }, + }, + }), + async (req: Request, res: Response) => { + const { guild_id } = req.params; + + const userIds: Array = req.body.user_ids; + if (!userIds) throw new HTTPError("The user_ids array is missing", 400); + if (userIds.length > 200) + throw new HTTPError( + "The user_ids array must be between 1 and 200 in length", + 400, + ); + + const banned_users = []; + const failed_users = []; + for await (const banned_user_id of userIds) { + if ( + req.user_id === banned_user_id && + banned_user_id === req.permission?.cache.guild?.owner_id + ) { + failed_users.push(banned_user_id); + continue; + } + + if (req.permission?.cache.guild?.owner_id === banned_user_id) { + failed_users.push(banned_user_id); + continue; + } + + const existingBan = await Ban.findOne({ + where: { guild_id: guild_id, user_id: banned_user_id }, + }); + if (existingBan) { + failed_users.push(banned_user_id); + continue; + } + + let banned_user; + try { + banned_user = await User.getPublicUser(banned_user_id); + } catch { + failed_users.push(banned_user_id); + continue; + } + + const ban = Ban.create({ + user_id: banned_user_id, + guild_id: guild_id, + ip: getIpAdress(req), + executor_id: req.user_id, + reason: req.body.reason, // || otherwise empty + }); + + try { + await Promise.all([ + Member.removeFromGuild(banned_user_id, guild_id), + ban.save(), + emitEvent({ + event: "GUILD_BAN_ADD", + data: { + guild_id: guild_id, + user: banned_user, + }, + guild_id: guild_id, + } as GuildBanAddEvent), + ]); + banned_users.push(banned_user_id); + } catch { + failed_users.push(banned_user_id); + continue; + } + } + + if (banned_users.length === 0 && failed_users.length > 0) + throw DiscordApiErrors.BULK_BAN_FAILED; + return res.json({ + banned_users: banned_users, + failed_users: failed_users, + }); + }, +); + +export default router; diff --git a/src/api/routes/guilds/#guild_id/channels.ts b/src/api/routes/guilds/#guild_id/channels.ts index 68208fee..3488b64d 100644 --- a/src/api/routes/guilds/#guild_id/channels.ts +++ b/src/api/routes/guilds/#guild_id/channels.ts @@ -1,17 +1,17 @@ /* Spacebar: A FOSS re-implementation and extension of the Discord.com backend. Copyright (C) 2023 Spacebar and Spacebar 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 . */ @@ -41,6 +41,15 @@ router.get( const { guild_id } = req.params; const channels = await Channel.find({ where: { guild_id } }); + for await (const channel of channels) { + channel.position = await Channel.calculatePosition( + channel.id, + guild_id, + channel.guild, + ); + } + channels.sort((a, b) => a.position - b.position); + res.json(channels); }, ); @@ -71,6 +80,11 @@ router.post( { ...body, guild_id }, req.user_id, ); + channel.position = await Channel.calculatePosition( + channel.id, + guild_id, + channel.guild, + ); res.status(201).json(channel); }, diff --git a/src/api/routes/guilds/#guild_id/emojis.ts b/src/api/routes/guilds/#guild_id/emojis.ts index ef28f989..f3f0fd8b 100644 --- a/src/api/routes/guilds/#guild_id/emojis.ts +++ b/src/api/routes/guilds/#guild_id/emojis.ts @@ -1,17 +1,17 @@ /* Spacebar: A FOSS re-implementation and extension of the Discord.com backend. Copyright (C) 2023 Spacebar and Spacebar 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 . */ @@ -125,6 +125,7 @@ router.post( const user = await User.findOneOrFail({ where: { id: req.user_id } }); body.image = (await handleFile(`/emojis/${id}`, body.image)) as string; + const mimeType = body.image.split(":")[1].split(";")[0]; const emoji = await Emoji.create({ id: id, guild_id: guild_id, @@ -132,7 +133,10 @@ router.post( require_colons: body.require_colons ?? undefined, // schema allows nulls, db does not user: user, managed: false, - animated: false, // TODO: Add support animated emojis + animated: + mimeType == "image/gif" || + mimeType == "image/apng" || + mimeType == "video/webm", available: true, roles: [], }).save(); diff --git a/src/api/routes/guilds/#guild_id/members/#member_id/index.ts b/src/api/routes/guilds/#guild_id/members/#member_id/index.ts index c168f2dc..a1ee88d2 100644 --- a/src/api/routes/guilds/#guild_id/members/#member_id/index.ts +++ b/src/api/routes/guilds/#guild_id/members/#member_id/index.ts @@ -113,9 +113,6 @@ router.patch( relations: ["roles", "user"], }); const permission = await getPermission(req.user_id, guild_id); - const everyone = await Role.findOneOrFail({ - where: { guild_id: guild_id, name: "@everyone", position: 0 }, - }); if ("nick" in body) { permission.hasThrow("MANAGE_NICKNAMES"); @@ -152,15 +149,14 @@ router.patch( body.roles = body.roles || []; body.roles.filter((x) => !!x); - if (body.roles.indexOf(everyone.id) === -1) - body.roles.push(everyone.id); + if (body.roles.indexOf(guild_id) === -1) body.roles.push(guild_id); // foreign key constraint will fail if role doesn't exist member.roles = body.roles.map((x) => Role.create({ id: x })); } await member.save(); - member.roles = member.roles.filter((x) => x.id !== everyone.id); + member.roles = member.roles.filter((x) => x.id !== guild_id); // do not use promise.all as we have to first write to db before emitting the event to catch errors await emitEvent({ diff --git a/src/api/routes/guilds/#guild_id/messages/search.ts b/src/api/routes/guilds/#guild_id/messages/search.ts index 637d1e43..94adf9c6 100644 --- a/src/api/routes/guilds/#guild_id/messages/search.ts +++ b/src/api/routes/guilds/#guild_id/messages/search.ts @@ -1,17 +1,17 @@ /* Spacebar: A FOSS re-implementation and extension of the Discord.com backend. Copyright (C) 2023 Spacebar and Spacebar 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 . */ @@ -162,6 +162,7 @@ router.get( edited_timestamp: x.edited_timestamp, flags: x.flags, components: x.components, + poll: x.poll, hit: true, }, ]); diff --git a/src/api/routes/users/#id/profile.ts b/src/api/routes/users/#id/profile.ts index eecec0f3..db0922d6 100644 --- a/src/api/routes/users/#id/profile.ts +++ b/src/api/routes/users/#id/profile.ts @@ -18,6 +18,7 @@ import { route } from "@spacebar/api"; import { + Badge, Member, PrivateUserProjection, User, @@ -98,6 +99,9 @@ router.get( bio: guild_member?.bio || "", guild_id, }; + + const badges = await Badge.find(); + res.json({ connected_accounts: user.connected_accounts.filter( (x) => x.visibility != 0, @@ -111,6 +115,7 @@ router.get( user_profile: userProfile, guild_member: guild_member?.toPublicMember(), guild_member_profile: guild_id && guildMemberProfile, + badges: badges.filter((x) => user.badge_ids?.includes(x.id)), }); }, ); diff --git a/src/api/util/handlers/Message.ts b/src/api/util/handlers/Message.ts index 0a20fbc8..9b267928 100644 --- a/src/api/util/handlers/Message.ts +++ b/src/api/util/handlers/Message.ts @@ -16,45 +16,49 @@ along with this program. If not, see . */ +import * as Sentry from "@sentry/node"; +import { EmbedHandlers } from "@spacebar/api"; import { + Application, + Attachment, Channel, + Config, Embed, + EmbedCache, emitEvent, - Guild, - Message, - MessageCreateEvent, - MessageUpdateEvent, + EVERYONE_MENTION, getPermission, getRights, + Guild, + HERE_MENTION, + Message, + MessageCreateEvent, + MessageCreateSchema, + MessageType, + MessageUpdateEvent, + Role, + ROLE_MENTION, + Sticker, + User, //CHANNEL_MENTION, USER_MENTION, - ROLE_MENTION, - Role, - EVERYONE_MENTION, - HERE_MENTION, - MessageType, - User, - Application, Webhook, Attachment, Config, Sticker, MessageCreateSchema, EmbedCache, - handleFile, - Permissions, } from "@spacebar/util"; import { HTTPError } from "lambert-server"; import { In } from "typeorm"; import { EmbedHandlers } from "@spacebar/api"; import * as Sentry from "@sentry/node"; -import fetch from "node-fetch"; const allow_empty = false; // TODO: check webhook, application, system author, stickers // TODO: embed gifs/videos/images const LINK_REGEX = - /https?:\/\/(www\.)?[-a-zA-Z0-9@:%._+~#=]{1,256}\.[a-zA-Z0-9()]{1,6}\b([-a-zA-Z0-9()@:%_+.~#?&//=]*)/g; + /?/g; export async function handleMessage(opts: MessageOptions): Promise { const channel = await Channel.findOneOrFail({ @@ -69,6 +73,7 @@ export async function handleMessage(opts: MessageOptions): Promise { : undefined; const message = Message.create({ ...opts, + poll: opts.poll, sticker_items: stickers, guild_id: channel.guild_id, channel_id: opts.channel_id, @@ -162,29 +167,28 @@ export async function handleMessage(opts: MessageOptions): Promise { message.member = permission.cache.member; } - if (opts.tts) permission.hasThrow("SEND_TTS_MESSAGES"); - if (opts.message_reference) { - permission.hasThrow("READ_MESSAGE_HISTORY"); - // code below has to be redone when we add custom message routing - if (message.guild_id !== null) { - const guild = await Guild.findOneOrFail({ - where: { id: channel.guild_id }, - }); - if (!guild.features.includes("CROSS_CHANNEL_REPLIES")) { - if (opts.message_reference.guild_id !== channel.guild_id) - throw new HTTPError( - "You can only reference messages from this guild", - ); - if (opts.message_reference.channel_id !== opts.channel_id) - throw new HTTPError( - "You can only reference messages from this channel", - ); - } + if (opts.tts) permission.hasThrow("SEND_TTS_MESSAGES"); + if (opts.message_reference) { + permission.hasThrow("READ_MESSAGE_HISTORY"); + // code below has to be redone when we add custom message routing + if (message.guild_id !== null) { + const guild = await Guild.findOneOrFail({ + where: { id: channel.guild_id }, + }); + if (!guild.features.includes("CROSS_CHANNEL_REPLIES")) { + if (opts.message_reference.guild_id !== channel.guild_id) + throw new HTTPError( + "You can only reference messages from this guild", + ); + if (opts.message_reference.channel_id !== opts.channel_id) + throw new HTTPError( + "You can only reference messages from this channel", + ); } - /** Q: should be checked if the referenced message exists? ANSWER: NO - otherwise backfilling won't work **/ - message.type = MessageType.REPLY; } + /** Q: should be checked if the referenced message exists? ANSWER: NO + otherwise backfilling won't work **/ + message.type = MessageType.REPLY; } // TODO: stickers/activity @@ -193,7 +197,9 @@ export async function handleMessage(opts: MessageOptions): Promise { !opts.content && !opts.embeds?.length && !opts.attachments?.length && - !opts.sticker_ids?.length + !opts.sticker_ids?.length && + !opts.poll && + !opts.components?.length ) { throw new HTTPError("Empty messages are not allowed", 50006); } @@ -272,6 +278,9 @@ export async function postHandleMessage(message: Message) { const cachePromises = []; for (const link of links) { + // Don't embed links in <> + if (link.startsWith("<") && link.endsWith(">")) continue; + const url = new URL(link); const cached = await EmbedCache.findOne({ where: { url: link } }); diff --git a/src/api/util/handlers/route.ts b/src/api/util/handlers/route.ts index 5a0b48e6..2c98783a 100644 --- a/src/api/util/handlers/route.ts +++ b/src/api/util/handlers/route.ts @@ -1,17 +1,17 @@ /* Spacebar: A FOSS re-implementation and extension of the Discord.com backend. Copyright (C) 2023 Spacebar and Spacebar 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 . */ @@ -90,19 +90,23 @@ export function route(opts: RouteOptions) { return async (req: Request, res: Response, next: NextFunction) => { if (opts.permission) { - const required = new Permissions(opts.permission); req.permission = await getPermission( req.user_id, req.params.guild_id, req.params.channel_id, ); - // bitfield comparison: check if user lacks certain permission - if (!req.permission.has(required)) { - throw DiscordApiErrors.MISSING_PERMISSIONS.withParams( - opts.permission as string, - ); - } + const requiredPerms = Array.isArray(opts.permission) + ? opts.permission + : [opts.permission]; + requiredPerms.forEach((perm) => { + // bitfield comparison: check if user lacks certain permission + if (!req.permission!.has(new Permissions(perm))) { + throw DiscordApiErrors.MISSING_PERMISSIONS.withParams( + perm as string, + ); + } + }); } if (opts.right) { diff --git a/src/cdn/routes/badge-icons.ts b/src/cdn/routes/badge-icons.ts new file mode 100644 index 00000000..04e96f2f --- /dev/null +++ b/src/cdn/routes/badge-icons.ts @@ -0,0 +1,40 @@ +/* + Spacebar: A FOSS re-implementation and extension of the Discord.com backend. + Copyright (C) 2023 Spacebar and Spacebar 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 . +*/ + +import { Router, Response, Request } from "express"; +import { storage } from "../util/Storage"; +import FileType from "file-type"; +import { HTTPError } from "lambert-server"; + +const router = Router(); + +router.get("/:badge_id", async (req: Request, res: Response) => { + const { badge_id } = req.params; + const path = `badge-icons/${badge_id}`; + + const file = await storage.get(path); + if (!file) throw new HTTPError("not found", 404); + const type = await FileType.fromBuffer(file); + + res.set("Content-Type", type?.mime); + res.set("Cache-Control", "public, max-age=31536000, must-revalidate"); + + return res.send(file); +}); + +export default router; diff --git a/src/cdn/routes/embed.ts b/src/cdn/routes/embed.ts index 9d3469cd..95ac720d 100644 --- a/src/cdn/routes/embed.ts +++ b/src/cdn/routes/embed.ts @@ -23,12 +23,12 @@ import { HTTPError } from "lambert-server"; import { join } from "path"; const defaultAvatarHashMap = new Map([ - ["0", "823a3de61c4dc2415cc4dbc38fca4299"], - ["1", "e56a89224be0b2b1f7c04eca975be468"], - ["2", "0c8138dcc0dfe2689cdd73f7952c2475"], - ["3", "5ac2728593bb455250d11b848a0c36c6"], - ["4", "addd2f3268df46459e1d6012ad8e75bd"], - ["5", "c4e0c8300fa491d94acfd2a1fb26cea8"], + ["0", "4a8562cf00887030c416d3ec2d46385a"], + ["1", "9b0bb198936784c45c72833cc426cc55"], + ["2", "22341bdb500c7b63a93bbce957d1601e"], + ["3", "d9977836b82058bf2f74eebd50edc095"], + ["4", "9d6ddb4e4d899a533a8cc617011351c9"], + ["5", "7213ab6677377974697dfdfbaf5f6a6f"], ]); const defaultGroupDMAvatarHashMap = new Map([ @@ -63,7 +63,15 @@ router.get("/avatars/:id", async (req: Request, res: Response) => { id = id.split(".")[0]; // remove .file extension const hash = defaultAvatarHashMap.get(id); if (!hash) throw new HTTPError("not found", 404); - const path = join(process.cwd(), "assets", "public", `${hash}.png`); + const path = join( + __dirname, + "..", + "..", + "..", + "assets", + "public", + `${hash}.png`, + ); const file = await getFile(path); if (!file) throw new HTTPError("not found", 404); @@ -80,7 +88,15 @@ router.get("/group-avatars/:id", async (req: Request, res: Response) => { id = id.split(".")[0]; // remove .file extension const hash = defaultGroupDMAvatarHashMap.get(id); if (!hash) throw new HTTPError("not found", 404); - const path = join(process.cwd(), "assets", "public", `${hash}.png`); + const path = join( + __dirname, + "..", + "..", + "..", + "assets", + "public", + `${hash}.png`, + ); const file = await getFile(path); if (!file) throw new HTTPError("not found", 404); diff --git a/src/connections/BattleNet/index.ts b/src/connections/BattleNet/index.ts index 4fdfccb1..8f44944c 100644 --- a/src/connections/BattleNet/index.ts +++ b/src/connections/BattleNet/index.ts @@ -1,17 +1,17 @@ /* Spacebar: A FOSS re-implementation and extension of the Discord.com backend. Copyright (C) 2023 Spacebar and Spacebar 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 . */ @@ -47,13 +47,15 @@ export default class BattleNetConnection extends Connection { settings: BattleNetSettings = new BattleNetSettings(); init(): void { - const settings = - ConnectionLoader.getConnectionConfig( - this.id, - this.settings, - ); + this.settings = ConnectionLoader.getConnectionConfig( + this.id, + this.settings, + ); - if (settings.enabled && (!settings.clientId || !settings.clientSecret)) + if ( + this.settings.enabled && + (!this.settings.clientId || !this.settings.clientSecret) + ) throw new Error(`Invalid settings for connection ${this.id}`); } diff --git a/src/connections/Discord/index.ts b/src/connections/Discord/index.ts index 731086f1..e5508f48 100644 --- a/src/connections/Discord/index.ts +++ b/src/connections/Discord/index.ts @@ -1,17 +1,17 @@ /* Spacebar: A FOSS re-implementation and extension of the Discord.com backend. Copyright (C) 2023 Spacebar and Spacebar 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 . */ @@ -43,12 +43,15 @@ export default class DiscordConnection extends Connection { settings: DiscordSettings = new DiscordSettings(); init(): void { - const settings = ConnectionLoader.getConnectionConfig( + this.settings = ConnectionLoader.getConnectionConfig( this.id, this.settings, ); - if (settings.enabled && (!settings.clientId || !settings.clientSecret)) + if ( + this.settings.enabled && + (!this.settings.clientId || !this.settings.clientSecret) + ) throw new Error(`Invalid settings for connection ${this.id}`); } diff --git a/src/connections/EpicGames/index.ts b/src/connections/EpicGames/index.ts index e5b2d336..cedfcd0a 100644 --- a/src/connections/EpicGames/index.ts +++ b/src/connections/EpicGames/index.ts @@ -1,17 +1,17 @@ /* Spacebar: A FOSS re-implementation and extension of the Discord.com backend. Copyright (C) 2023 Spacebar and Spacebar 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 . */ @@ -53,13 +53,15 @@ export default class EpicGamesConnection extends Connection { settings: EpicGamesSettings = new EpicGamesSettings(); init(): void { - const settings = - ConnectionLoader.getConnectionConfig( - this.id, - this.settings, - ); + this.settings = ConnectionLoader.getConnectionConfig( + this.id, + this.settings, + ); - if (settings.enabled && (!settings.clientId || !settings.clientSecret)) + if ( + this.settings.enabled && + (!this.settings.clientId || !this.settings.clientSecret) + ) throw new Error(`Invalid settings for connection ${this.id}`); } diff --git a/src/connections/Facebook/index.ts b/src/connections/Facebook/index.ts index 2bf26f34..bcb90b4c 100644 --- a/src/connections/Facebook/index.ts +++ b/src/connections/Facebook/index.ts @@ -1,17 +1,17 @@ /* Spacebar: A FOSS re-implementation and extension of the Discord.com backend. Copyright (C) 2023 Spacebar and Spacebar 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 . */ @@ -52,12 +52,15 @@ export default class FacebookConnection extends Connection { settings: FacebookSettings = new FacebookSettings(); init(): void { - const settings = ConnectionLoader.getConnectionConfig( + this.settings = ConnectionLoader.getConnectionConfig( this.id, this.settings, ); - if (settings.enabled && (!settings.clientId || !settings.clientSecret)) + if ( + this.settings.enabled && + (!this.settings.clientId || !this.settings.clientSecret) + ) throw new Error(`Invalid settings for connection ${this.id}`); } diff --git a/src/connections/GitHub/index.ts b/src/connections/GitHub/index.ts index 25e5f89f..78bf510e 100644 --- a/src/connections/GitHub/index.ts +++ b/src/connections/GitHub/index.ts @@ -1,17 +1,17 @@ /* Spacebar: A FOSS re-implementation and extension of the Discord.com backend. Copyright (C) 2023 Spacebar and Spacebar 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 . */ @@ -42,12 +42,15 @@ export default class GitHubConnection extends Connection { settings: GitHubSettings = new GitHubSettings(); init(): void { - const settings = ConnectionLoader.getConnectionConfig( + this.settings = ConnectionLoader.getConnectionConfig( this.id, this.settings, ); - if (settings.enabled && (!settings.clientId || !settings.clientSecret)) + if ( + this.settings.enabled && + (!this.settings.clientId || !this.settings.clientSecret) + ) throw new Error(`Invalid settings for connection ${this.id}`); } diff --git a/src/connections/Reddit/index.ts b/src/connections/Reddit/index.ts index 149cce02..0db23731 100644 --- a/src/connections/Reddit/index.ts +++ b/src/connections/Reddit/index.ts @@ -1,17 +1,17 @@ /* Spacebar: A FOSS re-implementation and extension of the Discord.com backend. Copyright (C) 2023 Spacebar and Spacebar 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 . */ @@ -54,12 +54,15 @@ export default class RedditConnection extends Connection { settings: RedditSettings = new RedditSettings(); init(): void { - const settings = ConnectionLoader.getConnectionConfig( + this.settings = ConnectionLoader.getConnectionConfig( this.id, this.settings, ); - if (settings.enabled && (!settings.clientId || !settings.clientSecret)) + if ( + this.settings.enabled && + (!this.settings.clientId || !this.settings.clientSecret) + ) throw new Error(`Invalid settings for connection ${this.id}`); } diff --git a/src/connections/Spotify/index.ts b/src/connections/Spotify/index.ts index ece404d8..4eb12602 100644 --- a/src/connections/Spotify/index.ts +++ b/src/connections/Spotify/index.ts @@ -1,17 +1,17 @@ /* Spacebar: A FOSS re-implementation and extension of the Discord.com backend. Copyright (C) 2023 Spacebar and Spacebar 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 . */ @@ -63,12 +63,16 @@ export default class SpotifyConnection extends RefreshableConnection { * So to prevent spamming the spotify api we disable the ability to refresh. */ this.refreshEnabled = false; - const settings = ConnectionLoader.getConnectionConfig( + + this.settings = ConnectionLoader.getConnectionConfig( this.id, this.settings, ); - if (settings.enabled && (!settings.clientId || !settings.clientSecret)) + if ( + this.settings.enabled && + (!this.settings.clientId || !this.settings.clientSecret) + ) throw new Error(`Invalid settings for connection ${this.id}`); } diff --git a/src/connections/Twitch/index.ts b/src/connections/Twitch/index.ts index 9a6cea35..953669a1 100644 --- a/src/connections/Twitch/index.ts +++ b/src/connections/Twitch/index.ts @@ -1,17 +1,17 @@ /* Spacebar: A FOSS re-implementation and extension of the Discord.com backend. Copyright (C) 2023 Spacebar and Spacebar 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 . */ @@ -55,12 +55,15 @@ export default class TwitchConnection extends RefreshableConnection { settings: TwitchSettings = new TwitchSettings(); init(): void { - const settings = ConnectionLoader.getConnectionConfig( + this.settings = ConnectionLoader.getConnectionConfig( this.id, this.settings, ); - if (settings.enabled && (!settings.clientId || !settings.clientSecret)) + if ( + this.settings.enabled && + (!this.settings.clientId || !this.settings.clientSecret) + ) throw new Error(`Invalid settings for connection ${this.id}`); } diff --git a/src/connections/Twitter/index.ts b/src/connections/Twitter/index.ts index 62fd7da1..eba8ceb5 100644 --- a/src/connections/Twitter/index.ts +++ b/src/connections/Twitter/index.ts @@ -1,17 +1,17 @@ /* Spacebar: A FOSS re-implementation and extension of the Discord.com backend. Copyright (C) 2023 Spacebar and Spacebar 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 . */ @@ -55,12 +55,15 @@ export default class TwitterConnection extends RefreshableConnection { settings: TwitterSettings = new TwitterSettings(); init(): void { - const settings = ConnectionLoader.getConnectionConfig( + this.settings = ConnectionLoader.getConnectionConfig( this.id, this.settings, ); - if (settings.enabled && (!settings.clientId || !settings.clientSecret)) + if ( + this.settings.enabled && + (!this.settings.clientId || !this.settings.clientSecret) + ) throw new Error(`Invalid settings for connection ${this.id}`); } diff --git a/src/connections/Xbox/index.ts b/src/connections/Xbox/index.ts index 935ff7ab..84066def 100644 --- a/src/connections/Xbox/index.ts +++ b/src/connections/Xbox/index.ts @@ -1,17 +1,17 @@ /* Spacebar: A FOSS re-implementation and extension of the Discord.com backend. Copyright (C) 2023 Spacebar and Spacebar 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 . */ @@ -62,12 +62,15 @@ export default class XboxConnection extends Connection { settings: XboxSettings = new XboxSettings(); init(): void { - const settings = ConnectionLoader.getConnectionConfig( + this.settings = ConnectionLoader.getConnectionConfig( this.id, this.settings, ); - if (settings.enabled && (!settings.clientId || !settings.clientSecret)) + if ( + this.settings.enabled && + (!this.settings.clientId || !this.settings.clientSecret) + ) throw new Error(`Invalid settings for connection ${this.id}`); } diff --git a/src/connections/Youtube/index.ts b/src/connections/Youtube/index.ts index 844803cf..38edbb0d 100644 --- a/src/connections/Youtube/index.ts +++ b/src/connections/Youtube/index.ts @@ -1,17 +1,17 @@ /* Spacebar: A FOSS re-implementation and extension of the Discord.com backend. Copyright (C) 2023 Spacebar and Spacebar 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 . */ @@ -62,12 +62,15 @@ export default class YoutubeConnection extends Connection { settings: YoutubeSettings = new YoutubeSettings(); init(): void { - const settings = ConnectionLoader.getConnectionConfig( + this.settings = ConnectionLoader.getConnectionConfig( this.id, this.settings, ); - if (settings.enabled && (!settings.clientId || !settings.clientSecret)) + if ( + this.settings.enabled && + (!this.settings.clientId || !this.settings.clientSecret) + ) throw new Error(`Invalid settings for connection ${this.id}`); } diff --git a/src/gateway/opcodes/Identify.ts b/src/gateway/opcodes/Identify.ts index 330ce561..41f9f83d 100644 --- a/src/gateway/opcodes/Identify.ts +++ b/src/gateway/opcodes/Identify.ts @@ -439,6 +439,10 @@ export async function onIdentify(this: WebSocket, data: Payload) { tutorial: null, session_type: "normal", // TODO auth_session_id_hash: "", // TODO + notification_settings: { + // ???? + flags: 0, + }, }; // Send READY diff --git a/src/util/config/types/EmailConfiguration.ts b/src/util/config/types/EmailConfiguration.ts index ae9d53ba..62305d10 100644 --- a/src/util/config/types/EmailConfiguration.ts +++ b/src/util/config/types/EmailConfiguration.ts @@ -25,6 +25,7 @@ import { SendGridConfiguration } from "./subconfigurations/email/SendGrid"; export class EmailConfiguration { provider: string | null = null; + senderAddress: string | null = null; smtp: SMTPConfiguration = new SMTPConfiguration(); mailgun: MailGunConfiguration = new MailGunConfiguration(); mailjet: MailJetConfiguration = new MailJetConfiguration(); diff --git a/src/util/connections/Connection.ts b/src/util/connections/Connection.ts index 5bdebd47..638dde2c 100644 --- a/src/util/connections/Connection.ts +++ b/src/util/connections/Connection.ts @@ -1,17 +1,17 @@ /* Spacebar: A FOSS re-implementation and extension of the Discord.com backend. Copyright (C) 2023 Spacebar and Spacebar 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 . */ @@ -43,7 +43,7 @@ export abstract class Connection { */ getRedirectUri() { const endpointPublic = - Config.get().api.endpointPublic ?? "http://localhost:3001"; + Config.get().general.frontPage ?? "http://localhost:3001"; return `${endpointPublic}/connections/${this.id}/callback`; } diff --git a/src/util/connections/ConnectionLoader.ts b/src/util/connections/ConnectionLoader.ts index e9dc6973..31b8e04b 100644 --- a/src/util/connections/ConnectionLoader.ts +++ b/src/util/connections/ConnectionLoader.ts @@ -22,7 +22,7 @@ import path from "path"; import { ConnectionConfig } from "./ConnectionConfig"; import { ConnectionStore } from "./ConnectionStore"; -const root = "dist/connections"; +const root = path.join(__dirname, "..", "..", "connections"); const connectionsLoaded = false; export class ConnectionLoader { diff --git a/src/util/dtos/UserDTO.ts b/src/util/dtos/UserDTO.ts index a24c8d96..17e4435f 100644 --- a/src/util/dtos/UserDTO.ts +++ b/src/util/dtos/UserDTO.ts @@ -24,6 +24,7 @@ export class MinimalPublicUserDTO { id: string; public_flags: number; username: string; + badge_ids?: string[] | null; constructor(user: User) { this.avatar = user.avatar; @@ -31,5 +32,6 @@ export class MinimalPublicUserDTO { this.id = user.id; this.public_flags = user.public_flags; this.username = user.username; + this.badge_ids = user.badge_ids; } } diff --git a/src/util/entities/Badge.ts b/src/util/entities/Badge.ts new file mode 100644 index 00000000..9535e207 --- /dev/null +++ b/src/util/entities/Badge.ts @@ -0,0 +1,35 @@ +/* + Spacebar: A FOSS re-implementation and extension of the Discord.com backend. + Copyright (C) 2023 Spacebar and Spacebar 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 . +*/ + +import { Column, Entity } from "typeorm"; +import { BaseClassWithoutId } from "./BaseClass"; + +@Entity("badges") +export class Badge extends BaseClassWithoutId { + @Column({ primary: true }) + id: string; + + @Column() + description: string; + + @Column() + icon: string; + + @Column({ nullable: true }) + link?: string; +} diff --git a/src/util/entities/Channel.ts b/src/util/entities/Channel.ts index 169eab3d..71ccf49e 100644 --- a/src/util/entities/Channel.ts +++ b/src/util/entities/Channel.ts @@ -1,17 +1,17 @@ /* Spacebar: A FOSS re-implementation and extension of the Discord.com backend. Copyright (C) 2023 Spacebar and Spacebar 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 . */ @@ -105,7 +105,7 @@ export class Channel extends BaseClass { @Column({ nullable: true }) @RelationId((channel: Channel) => channel.parent) - parent_id: string; + parent_id: string | null; @JoinColumn({ name: "parent_id" }) @ManyToOne(() => Channel) diff --git a/src/util/entities/Member.ts b/src/util/entities/Member.ts index 65942816..3ef778ac 100644 --- a/src/util/entities/Member.ts +++ b/src/util/entities/Member.ts @@ -1,17 +1,17 @@ /* Spacebar: A FOSS re-implementation and extension of the Discord.com backend. Copyright (C) 2023 Spacebar and Spacebar 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 . */ @@ -31,7 +31,7 @@ import { PrimaryGeneratedColumn, RelationId, } from "typeorm"; -import { Ban, PublicGuildRelations } from "."; +import { Ban, Channel, PublicGuildRelations } from "."; import { ReadyGuildDTO } from "../dtos"; import { GuildCreateEvent, @@ -330,6 +330,13 @@ export class Member extends BaseClassWithoutId { relationLoadStrategy: "query", }); + for await (const channel of guild.channels) { + channel.position = await Channel.calculatePosition( + channel.id, + guild_id, + ); + } + const memberCount = await Member.count({ where: { guild_id } }); const memberPreview = ( diff --git a/src/util/entities/Message.ts b/src/util/entities/Message.ts index 4a1ed5b4..e70d6821 100644 --- a/src/util/entities/Message.ts +++ b/src/util/entities/Message.ts @@ -192,8 +192,8 @@ export class Message extends BaseClass { party_id: string; }; - @Column({ nullable: true }) - flags?: number; + @Column({ default: 0 }) + flags: number; @Column({ type: "simple-json", nullable: true }) message_reference?: { @@ -252,6 +252,7 @@ export class Message extends BaseClass { activity: this.activity ?? undefined, application: this.application ?? undefined, components: this.components ?? undefined, + poll: this.poll ?? undefined, content: this.content ?? "", }; } @@ -263,6 +264,7 @@ export interface MessageComponent { label?: string; emoji?: PartialEmoji; custom_id?: string; + sku_id?: string; url?: string; disabled?: boolean; components: MessageComponent[]; @@ -341,3 +343,32 @@ export interface AllowedMentions { users?: string[]; replied_user?: boolean; } + +export interface Poll { + question: PollMedia; + answers: PollAnswer[]; + expiry: Date; + allow_multiselect: boolean; + results?: PollResult; +} + +export interface PollMedia { + text?: string; + emoji?: PartialEmoji; +} + +export interface PollAnswer { + answer_id?: string; + poll_media: PollMedia; +} + +export interface PollResult { + is_finalized: boolean; + answer_counts: PollAnswerCount[]; +} + +export interface PollAnswerCount { + id: string; + count: number; + me_voted: boolean; +} diff --git a/src/util/entities/User.ts b/src/util/entities/User.ts index c6582b00..c929039e 100644 --- a/src/util/entities/User.ts +++ b/src/util/entities/User.ts @@ -49,6 +49,7 @@ export enum PublicUserEnum { premium_type, theme_colors, pronouns, + badge_ids, } export type PublicUserKeys = keyof typeof PublicUserEnum; @@ -231,6 +232,9 @@ export class User extends BaseClass { @OneToMany(() => SecurityKey, (key: SecurityKey) => key.user) security_keys: SecurityKey[]; + @Column({ type: "simple-array", nullable: true }) + badge_ids?: string[]; + // TODO: I don't like this method? validate() { if (this.discriminator) { diff --git a/src/util/entities/UserSettings.ts b/src/util/entities/UserSettings.ts index 0d5d9aad..d3efe79b 100644 --- a/src/util/entities/UserSettings.ts +++ b/src/util/entities/UserSettings.ts @@ -63,6 +63,9 @@ export class UserSettings extends BaseClassWithoutId { @Column({ nullable: true }) explicit_content_filter: number = 0; + @Column({ nullable: true }) + friend_discovery_flags: number = 0; + @Column({ nullable: true, type: "simple-json" }) friend_source_flags: FriendSourceFlags = { all: true }; @@ -116,6 +119,9 @@ export class UserSettings extends BaseClassWithoutId { @Column({ nullable: true }) timezone_offset: number = 0; // e.g -60 + + @Column({ nullable: true }) + view_nsfw_guilds: boolean = true; } interface CustomStatus { diff --git a/src/util/entities/index.ts b/src/util/entities/index.ts index aa943dca..b2356aa7 100644 --- a/src/util/entities/index.ts +++ b/src/util/entities/index.ts @@ -20,6 +20,7 @@ export * from "./Application"; export * from "./Attachment"; export * from "./AuditLog"; export * from "./BackupCodes"; +export * from "./Badge"; export * from "./Ban"; export * from "./BaseClass"; export * from "./Categories"; diff --git a/src/util/interfaces/Event.ts b/src/util/interfaces/Event.ts index deb54428..98a64e94 100644 --- a/src/util/interfaces/Event.ts +++ b/src/util/interfaces/Event.ts @@ -129,6 +129,9 @@ export interface ReadyEventData { | "REQUIRE_CAPTCHA" // TODO: allow these to be triggered | "TOS_UPDATE_ACKNOWLEDGMENT" | "AGREEMENTS"; + notification_settings: { + flags: number; + }; } export interface ReadyEvent extends Event { diff --git a/src/util/migration/mariadb/1713116476900-messageFlagsNotNull.ts b/src/util/migration/mariadb/1713116476900-messageFlagsNotNull.ts new file mode 100644 index 00000000..7be2ad70 --- /dev/null +++ b/src/util/migration/mariadb/1713116476900-messageFlagsNotNull.ts @@ -0,0 +1,25 @@ +import { MigrationInterface, QueryRunner } from "typeorm"; + +export class MessageFlagsNotNull1713116476900 implements MigrationInterface { + name = "MessageFlagsNotNull1713116476900"; + + public async up(queryRunner: QueryRunner): Promise { + await queryRunner.query( + "ALTER TABLE `messages` CHANGE flags flags_old integer;", + ); + await queryRunner.query( + "ALTER TABLE `messages` ADD flags integer NOT NULL DEFAULT 0;", + ); + await queryRunner.query( + "UPDATE `messages` SET flags = IFNULL(flags_old, 0);", + ); + await queryRunner.query( + "ALTER TABLE `messages` DROP COLUMN flags_old;", + ); + } + + public async down(): Promise { + // dont care + throw new Error("Migration down is not implemented."); + } +} diff --git a/src/util/migration/mariadb/1719776735000-newUserSettings.ts b/src/util/migration/mariadb/1719776735000-newUserSettings.ts new file mode 100644 index 00000000..f7c37ca9 --- /dev/null +++ b/src/util/migration/mariadb/1719776735000-newUserSettings.ts @@ -0,0 +1,23 @@ +import { MigrationInterface, QueryRunner } from "typeorm"; + +export class NewUserSettings1719776735000 implements MigrationInterface { + name = "NewUserSettings1719776735000"; + + public async up(queryRunner: QueryRunner): Promise { + await queryRunner.query( + "ALTER TABLE `user_settings` ADD friend_discovery_flags integer NULL DEFAULT 0;", + ); + await queryRunner.query( + "ALTER TABLE `user_settings` ADD view_nsfw_guilds tinyint NULL DEFAULT 1;", + ); + } + + public async down(queryRunner: QueryRunner): Promise { + await queryRunner.query( + "ALTER TABLE `user_settings` DROP COLUMN friend_discovery_flags;", + ); + await queryRunner.query( + "ALTER TABLE `user_settings` DROP COLUMN view_nsfw_guilds;", + ); + } +} diff --git a/src/util/migration/mariadb/1720157926878-messagePollObject.ts b/src/util/migration/mariadb/1720157926878-messagePollObject.ts new file mode 100644 index 00000000..c0866426 --- /dev/null +++ b/src/util/migration/mariadb/1720157926878-messagePollObject.ts @@ -0,0 +1,13 @@ +import { MigrationInterface, QueryRunner } from "typeorm"; + +export class MessagePollObject1720157926878 implements MigrationInterface { + name = "MessagePollObject1720157926878"; + + public async up(queryRunner: QueryRunner): Promise { + await queryRunner.query("ALTER TABLE `messages` ADD `poll` text NULL"); + } + + public async down(queryRunner: QueryRunner): Promise { + await queryRunner.query("ALTER TABLE `messages` DROP COLUMN `poll`"); + } +} diff --git a/src/util/migration/mariadb/1720628601997-badges.ts b/src/util/migration/mariadb/1720628601997-badges.ts new file mode 100644 index 00000000..af298e42 --- /dev/null +++ b/src/util/migration/mariadb/1720628601997-badges.ts @@ -0,0 +1,21 @@ +import { MigrationInterface, QueryRunner } from "typeorm"; + +export class Badges1720628601997 implements MigrationInterface { + name = "Badges1720628601997"; + + public async up(queryRunner: QueryRunner): Promise { + await queryRunner.query( + `CREATE TABLE \`badges\` (\`id\` varchar(255) NOT NULL, \`description\` varchar(255) NOT NULL, \`icon\` varchar(255) NOT NULL, \`link\` varchar(255) NULL, PRIMARY KEY (\`id\`)) ENGINE=InnoDB`, + ); + await queryRunner.query( + `ALTER TABLE \`users\` ADD \`badge_ids\` text NULL`, + ); + } + + public async down(queryRunner: QueryRunner): Promise { + await queryRunner.query( + `ALTER TABLE \`users\` DROP COLUMN \`badge_ids\``, + ); + await queryRunner.query(`DROP TABLE \`badges\``); + } +} diff --git a/src/util/migration/mysql/1713116476900-messageFlagsNotNull.ts b/src/util/migration/mysql/1713116476900-messageFlagsNotNull.ts new file mode 100644 index 00000000..7be2ad70 --- /dev/null +++ b/src/util/migration/mysql/1713116476900-messageFlagsNotNull.ts @@ -0,0 +1,25 @@ +import { MigrationInterface, QueryRunner } from "typeorm"; + +export class MessageFlagsNotNull1713116476900 implements MigrationInterface { + name = "MessageFlagsNotNull1713116476900"; + + public async up(queryRunner: QueryRunner): Promise { + await queryRunner.query( + "ALTER TABLE `messages` CHANGE flags flags_old integer;", + ); + await queryRunner.query( + "ALTER TABLE `messages` ADD flags integer NOT NULL DEFAULT 0;", + ); + await queryRunner.query( + "UPDATE `messages` SET flags = IFNULL(flags_old, 0);", + ); + await queryRunner.query( + "ALTER TABLE `messages` DROP COLUMN flags_old;", + ); + } + + public async down(): Promise { + // dont care + throw new Error("Migration down is not implemented."); + } +} diff --git a/src/util/migration/mysql/1719776735000-newUserSettings.ts b/src/util/migration/mysql/1719776735000-newUserSettings.ts new file mode 100644 index 00000000..f7c37ca9 --- /dev/null +++ b/src/util/migration/mysql/1719776735000-newUserSettings.ts @@ -0,0 +1,23 @@ +import { MigrationInterface, QueryRunner } from "typeorm"; + +export class NewUserSettings1719776735000 implements MigrationInterface { + name = "NewUserSettings1719776735000"; + + public async up(queryRunner: QueryRunner): Promise { + await queryRunner.query( + "ALTER TABLE `user_settings` ADD friend_discovery_flags integer NULL DEFAULT 0;", + ); + await queryRunner.query( + "ALTER TABLE `user_settings` ADD view_nsfw_guilds tinyint NULL DEFAULT 1;", + ); + } + + public async down(queryRunner: QueryRunner): Promise { + await queryRunner.query( + "ALTER TABLE `user_settings` DROP COLUMN friend_discovery_flags;", + ); + await queryRunner.query( + "ALTER TABLE `user_settings` DROP COLUMN view_nsfw_guilds;", + ); + } +} diff --git a/src/util/migration/mysql/1720157926878-messagePollObject.ts b/src/util/migration/mysql/1720157926878-messagePollObject.ts new file mode 100644 index 00000000..c0866426 --- /dev/null +++ b/src/util/migration/mysql/1720157926878-messagePollObject.ts @@ -0,0 +1,13 @@ +import { MigrationInterface, QueryRunner } from "typeorm"; + +export class MessagePollObject1720157926878 implements MigrationInterface { + name = "MessagePollObject1720157926878"; + + public async up(queryRunner: QueryRunner): Promise { + await queryRunner.query("ALTER TABLE `messages` ADD `poll` text NULL"); + } + + public async down(queryRunner: QueryRunner): Promise { + await queryRunner.query("ALTER TABLE `messages` DROP COLUMN `poll`"); + } +} diff --git a/src/util/migration/mysql/1720628601997-badges.ts b/src/util/migration/mysql/1720628601997-badges.ts new file mode 100644 index 00000000..af298e42 --- /dev/null +++ b/src/util/migration/mysql/1720628601997-badges.ts @@ -0,0 +1,21 @@ +import { MigrationInterface, QueryRunner } from "typeorm"; + +export class Badges1720628601997 implements MigrationInterface { + name = "Badges1720628601997"; + + public async up(queryRunner: QueryRunner): Promise { + await queryRunner.query( + `CREATE TABLE \`badges\` (\`id\` varchar(255) NOT NULL, \`description\` varchar(255) NOT NULL, \`icon\` varchar(255) NOT NULL, \`link\` varchar(255) NULL, PRIMARY KEY (\`id\`)) ENGINE=InnoDB`, + ); + await queryRunner.query( + `ALTER TABLE \`users\` ADD \`badge_ids\` text NULL`, + ); + } + + public async down(queryRunner: QueryRunner): Promise { + await queryRunner.query( + `ALTER TABLE \`users\` DROP COLUMN \`badge_ids\``, + ); + await queryRunner.query(`DROP TABLE \`badges\``); + } +} diff --git a/src/util/migration/postgres/1713116476900-messageFlagsNotNull.ts b/src/util/migration/postgres/1713116476900-messageFlagsNotNull.ts new file mode 100644 index 00000000..026b069b --- /dev/null +++ b/src/util/migration/postgres/1713116476900-messageFlagsNotNull.ts @@ -0,0 +1,23 @@ +import { MigrationInterface, QueryRunner } from "typeorm"; + +export class MessageFlagsNotNull1713116476900 implements MigrationInterface { + name = "MessageFlagsNotNull1713116476900"; + + public async up(queryRunner: QueryRunner): Promise { + await queryRunner.query( + "ALTER TABLE messages RENAME COLUMN flags TO flags_old;", + ); + await queryRunner.query( + "ALTER TABLE messages ADD COLUMN flags integer NOT NULL DEFAULT 0;", + ); + await queryRunner.query( + "UPDATE messages SET flags = COALESCE(flags_old, 0);", + ); + await queryRunner.query("ALTER TABLE messages DROP COLUMN flags_old;"); + } + + public async down(): Promise { + // dont care + throw new Error("Migration down is not implemented."); + } +} diff --git a/src/util/migration/postgres/1719776735000-newUserSettings.ts b/src/util/migration/postgres/1719776735000-newUserSettings.ts new file mode 100644 index 00000000..dbee0b0d --- /dev/null +++ b/src/util/migration/postgres/1719776735000-newUserSettings.ts @@ -0,0 +1,23 @@ +import { MigrationInterface, QueryRunner } from "typeorm"; + +export class NewUserSettings1719776735000 implements MigrationInterface { + name = "NewUserSettings1719776735000"; + + public async up(queryRunner: QueryRunner): Promise { + await queryRunner.query( + "ALTER TABLE user_settings ADD COLUMN friend_discovery_flags integer DEFAULT 0;", + ); + await queryRunner.query( + "ALTER TABLE user_settings ADD COLUMN view_nsfw_guilds boolean DEFAULT true;", + ); + } + + public async down(queryRunner: QueryRunner): Promise { + await queryRunner.query( + "ALTER TABLE user_settings DROP COLUMN friend_discovery_flags;", + ); + await queryRunner.query( + "ALTER TABLE user_settings DROP COLUMN view_nsfw_guilds;", + ); + } +} diff --git a/src/util/migration/postgres/1720157926878-messagePollObject.ts b/src/util/migration/postgres/1720157926878-messagePollObject.ts new file mode 100644 index 00000000..7c3c95a0 --- /dev/null +++ b/src/util/migration/postgres/1720157926878-messagePollObject.ts @@ -0,0 +1,13 @@ +import { MigrationInterface, QueryRunner } from "typeorm"; + +export class MessagePollObject1720157926878 implements MigrationInterface { + name = "MessagePollObject1720157926878"; + + public async up(queryRunner: QueryRunner): Promise { + await queryRunner.query("ALTER TABLE messages ADD poll text NULL"); + } + + public async down(queryRunner: QueryRunner): Promise { + await queryRunner.query("ALTER TABLE messages DROP COLUMN poll"); + } +} diff --git a/src/util/migration/postgres/1720628601997-badges.ts b/src/util/migration/postgres/1720628601997-badges.ts new file mode 100644 index 00000000..f7b9958b --- /dev/null +++ b/src/util/migration/postgres/1720628601997-badges.ts @@ -0,0 +1,16 @@ +import { MigrationInterface, QueryRunner } from "typeorm"; + +export class Badges1720628601997 implements MigrationInterface { + name = "Badges1720628601997"; + + public async up(queryRunner: QueryRunner): Promise { + await queryRunner.query( + `CREATE TABLE "badges" ("id" character varying NOT NULL, "description" character varying NOT NULL, "icon" character varying NOT NULL, "link" character varying, CONSTRAINT "PK_8a651318b8de577e8e217676466" PRIMARY KEY ("id"))`, + ); + await queryRunner.query(`ALTER TABLE "users" ADD "badge_ids" text`); + } + + public async down(queryRunner: QueryRunner): Promise { + await queryRunner.query(`ALTER TABLE "users" DROP COLUMN "badge_ids"`); + } +} diff --git a/src/util/schemas/BulkBanSchema.ts b/src/util/schemas/BulkBanSchema.ts new file mode 100644 index 00000000..48a7bac8 --- /dev/null +++ b/src/util/schemas/BulkBanSchema.ts @@ -0,0 +1,22 @@ +/* + Spacebar: A FOSS re-implementation and extension of the Discord.com backend. + Copyright (C) 2023 Spacebar and Spacebar 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 . +*/ + +export interface BulkBanSchema { + user_ids: string[]; + delete_message_seconds?: number; +} diff --git a/src/util/schemas/MessageCreateSchema.ts b/src/util/schemas/MessageCreateSchema.ts index 8093a10a..d7e47556 100644 --- a/src/util/schemas/MessageCreateSchema.ts +++ b/src/util/schemas/MessageCreateSchema.ts @@ -1,22 +1,22 @@ /* Spacebar: A FOSS re-implementation and extension of the Discord.com backend. Copyright (C) 2023 Spacebar and Spacebar 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 . */ -import { Embed } from "@spacebar/util"; +import { Embed, MessageComponent, PollAnswer, PollMedia } from "@spacebar/util"; export type MessageCreateAttachment = { id: string; @@ -42,7 +42,7 @@ export interface MessageCreateSchema { }; message_reference?: { message_id: string; - channel_id: string; + channel_id?: string; guild_id?: string; fail_if_not_exists?: boolean; }; @@ -54,6 +54,21 @@ export interface MessageCreateSchema { **/ attachments?: MessageCreateAttachment[]; sticker_ids?: string[]; - // eslint-disable-next-line @typescript-eslint/no-explicit-any - components?: any[]; + components?: MessageComponent[]; + // TODO: Fix TypeScript errors in src\api\util\handlers\Message.ts once this is enabled + poll?: PollCreationSchema; + enforce_nonce?: boolean; // For Discord compatibility, it's the default behavior here + applied_tags?: string[]; // Not implemented yet, for webhooks in forums + thread_name?: string; // Not implemented yet, for webhooks + avatar_url?: string; // Not implemented yet, for webhooks +} + +// TypeScript complains once this is used above +// eslint-disable-next-line @typescript-eslint/no-unused-vars +interface PollCreationSchema { + question: PollMedia; + answers: PollAnswer[]; + duration?: number; + allow_multiselect?: boolean; + layout_type?: number; } diff --git a/src/util/schemas/responses/APIErrorOrCaptchaResponse.ts b/src/util/schemas/responses/APIErrorOrCaptchaResponse.ts index c9a0e5be..fd89a478 100644 --- a/src/util/schemas/responses/APIErrorOrCaptchaResponse.ts +++ b/src/util/schemas/responses/APIErrorOrCaptchaResponse.ts @@ -1,3 +1,21 @@ +/* + Spacebar: A FOSS re-implementation and extension of the Discord.com backend. + Copyright (C) 2023 Spacebar and Spacebar 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 . +*/ + import { APIErrorResponse } from "./APIErrorResponse"; import { CaptchaRequiredResponse } from "./CaptchaRequiredResponse"; diff --git a/src/util/schemas/responses/APIErrorResponse.ts b/src/util/schemas/responses/APIErrorResponse.ts index 25bb9504..547ee58d 100644 --- a/src/util/schemas/responses/APIErrorResponse.ts +++ b/src/util/schemas/responses/APIErrorResponse.ts @@ -1,3 +1,21 @@ +/* + Spacebar: A FOSS re-implementation and extension of the Discord.com backend. + Copyright (C) 2023 Spacebar and Spacebar 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 . +*/ + export interface APIErrorResponse { code: number; message: string; diff --git a/src/util/schemas/responses/BackupCodesChallengeResponse.ts b/src/util/schemas/responses/BackupCodesChallengeResponse.ts index 5473ad1f..b587845d 100644 --- a/src/util/schemas/responses/BackupCodesChallengeResponse.ts +++ b/src/util/schemas/responses/BackupCodesChallengeResponse.ts @@ -1,3 +1,21 @@ +/* + Spacebar: A FOSS re-implementation and extension of the Discord.com backend. + Copyright (C) 2023 Spacebar and Spacebar 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 . +*/ + export interface BackupCodesChallengeResponse { nonce: string; regenerate_nonce: string; diff --git a/src/util/schemas/responses/CaptchaRequiredResponse.ts b/src/util/schemas/responses/CaptchaRequiredResponse.ts index 9f7f02ff..a58e6054 100644 --- a/src/util/schemas/responses/CaptchaRequiredResponse.ts +++ b/src/util/schemas/responses/CaptchaRequiredResponse.ts @@ -1,3 +1,21 @@ +/* + Spacebar: A FOSS re-implementation and extension of the Discord.com backend. + Copyright (C) 2023 Spacebar and Spacebar 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 . +*/ + export interface CaptchaRequiredResponse { captcha_key: string; captcha_sitekey: string; diff --git a/src/util/schemas/responses/DiscoverableGuildsResponse.ts b/src/util/schemas/responses/DiscoverableGuildsResponse.ts index 2a9fb1bd..dc475902 100644 --- a/src/util/schemas/responses/DiscoverableGuildsResponse.ts +++ b/src/util/schemas/responses/DiscoverableGuildsResponse.ts @@ -1,3 +1,21 @@ +/* + Spacebar: A FOSS re-implementation and extension of the Discord.com backend. + Copyright (C) 2023 Spacebar and Spacebar 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 . +*/ + import { Guild } from "../../entities"; export interface DiscoverableGuildsResponse { diff --git a/src/util/schemas/responses/GatewayBotResponse.ts b/src/util/schemas/responses/GatewayBotResponse.ts index 30f1f57f..c68ec09e 100644 --- a/src/util/schemas/responses/GatewayBotResponse.ts +++ b/src/util/schemas/responses/GatewayBotResponse.ts @@ -1,3 +1,21 @@ +/* + Spacebar: A FOSS re-implementation and extension of the Discord.com backend. + Copyright (C) 2023 Spacebar and Spacebar 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 . +*/ + export interface GatewayBotResponse { url: string; shards: number; diff --git a/src/util/schemas/responses/GatewayResponse.ts b/src/util/schemas/responses/GatewayResponse.ts index e909f7bd..5b771edc 100644 --- a/src/util/schemas/responses/GatewayResponse.ts +++ b/src/util/schemas/responses/GatewayResponse.ts @@ -1,3 +1,21 @@ +/* + Spacebar: A FOSS re-implementation and extension of the Discord.com backend. + Copyright (C) 2023 Spacebar and Spacebar 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 . +*/ + export interface GatewayResponse { url: string; } diff --git a/src/util/schemas/responses/GenerateRegistrationTokensResponse.ts b/src/util/schemas/responses/GenerateRegistrationTokensResponse.ts index 8816eabf..4931eb5a 100644 --- a/src/util/schemas/responses/GenerateRegistrationTokensResponse.ts +++ b/src/util/schemas/responses/GenerateRegistrationTokensResponse.ts @@ -1,3 +1,21 @@ +/* + Spacebar: A FOSS re-implementation and extension of the Discord.com backend. + Copyright (C) 2023 Spacebar and Spacebar 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 . +*/ + export interface GenerateRegistrationTokensResponse { tokens: string[]; } diff --git a/src/util/schemas/responses/GuildBansResponse.ts b/src/util/schemas/responses/GuildBansResponse.ts index 876a4bc4..77c95a48 100644 --- a/src/util/schemas/responses/GuildBansResponse.ts +++ b/src/util/schemas/responses/GuildBansResponse.ts @@ -1,3 +1,21 @@ +/* + Spacebar: A FOSS re-implementation and extension of the Discord.com backend. + Copyright (C) 2023 Spacebar and Spacebar 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 . +*/ + export interface GuildBansResponse { reason: string; user: { diff --git a/src/util/schemas/responses/GuildCreateResponse.ts b/src/util/schemas/responses/GuildCreateResponse.ts index 8185cb86..5b2bf25d 100644 --- a/src/util/schemas/responses/GuildCreateResponse.ts +++ b/src/util/schemas/responses/GuildCreateResponse.ts @@ -1,3 +1,21 @@ +/* + Spacebar: A FOSS re-implementation and extension of the Discord.com backend. + Copyright (C) 2023 Spacebar and Spacebar 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 . +*/ + export interface GuildCreateResponse { id: string; } diff --git a/src/util/schemas/responses/GuildDiscoveryRequirements.ts b/src/util/schemas/responses/GuildDiscoveryRequirements.ts index 731976f7..1c1ea0ad 100644 --- a/src/util/schemas/responses/GuildDiscoveryRequirements.ts +++ b/src/util/schemas/responses/GuildDiscoveryRequirements.ts @@ -1,3 +1,21 @@ +/* + Spacebar: A FOSS re-implementation and extension of the Discord.com backend. + Copyright (C) 2023 Spacebar and Spacebar 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 . +*/ + export interface GuildDiscoveryRequirementsResponse { uild_id: string; safe_environment: boolean; diff --git a/src/util/schemas/responses/GuildMessagesSearchResponse.ts b/src/util/schemas/responses/GuildMessagesSearchResponse.ts index 0b6248b7..6121983e 100644 --- a/src/util/schemas/responses/GuildMessagesSearchResponse.ts +++ b/src/util/schemas/responses/GuildMessagesSearchResponse.ts @@ -1,7 +1,27 @@ +/* + Spacebar: A FOSS re-implementation and extension of the Discord.com backend. + Copyright (C) 2023 Spacebar and Spacebar 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 . +*/ + import { Attachment, Embed, + MessageComponent, MessageType, + Poll, PublicUser, Role, } from "../../entities"; @@ -22,7 +42,8 @@ export interface GuildMessagesSearchMessage { timestamp: string; edited_timestamp: string | null; flags: number; - components: unknown[]; + components: MessageComponent[]; + poll: Poll; hit: true; } diff --git a/src/util/schemas/responses/GuildPruneResponse.ts b/src/util/schemas/responses/GuildPruneResponse.ts index fb1abb89..2a24ef66 100644 --- a/src/util/schemas/responses/GuildPruneResponse.ts +++ b/src/util/schemas/responses/GuildPruneResponse.ts @@ -1,3 +1,21 @@ +/* + Spacebar: A FOSS re-implementation and extension of the Discord.com backend. + Copyright (C) 2023 Spacebar and Spacebar 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 . +*/ + export interface GuildPruneResponse { pruned: number; } diff --git a/src/util/schemas/responses/GuildRecommendationsResponse.ts b/src/util/schemas/responses/GuildRecommendationsResponse.ts index 211670a6..db67ff67 100644 --- a/src/util/schemas/responses/GuildRecommendationsResponse.ts +++ b/src/util/schemas/responses/GuildRecommendationsResponse.ts @@ -1,3 +1,21 @@ +/* + Spacebar: A FOSS re-implementation and extension of the Discord.com backend. + Copyright (C) 2023 Spacebar and Spacebar 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 . +*/ + import { Guild } from "../../entities"; export interface GuildRecommendationsResponse { diff --git a/src/util/schemas/responses/GuildVanityUrl.ts b/src/util/schemas/responses/GuildVanityUrl.ts index ff37bf4e..c6595a66 100644 --- a/src/util/schemas/responses/GuildVanityUrl.ts +++ b/src/util/schemas/responses/GuildVanityUrl.ts @@ -1,3 +1,21 @@ +/* + Spacebar: A FOSS re-implementation and extension of the Discord.com backend. + Copyright (C) 2023 Spacebar and Spacebar 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 . +*/ + export interface GuildVanityUrl { code: string; uses: number; diff --git a/src/util/schemas/responses/GuildVoiceRegionsResponse.ts b/src/util/schemas/responses/GuildVoiceRegionsResponse.ts index 8190d5fd..63a77f86 100644 --- a/src/util/schemas/responses/GuildVoiceRegionsResponse.ts +++ b/src/util/schemas/responses/GuildVoiceRegionsResponse.ts @@ -1,3 +1,21 @@ +/* + Spacebar: A FOSS re-implementation and extension of the Discord.com backend. + Copyright (C) 2023 Spacebar and Spacebar 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 . +*/ + export interface GuildVoiceRegion { id: string; name: string; diff --git a/src/util/schemas/responses/GuildWidgetJsonResponse.ts b/src/util/schemas/responses/GuildWidgetJsonResponse.ts index ef85dd08..bd692304 100644 --- a/src/util/schemas/responses/GuildWidgetJsonResponse.ts +++ b/src/util/schemas/responses/GuildWidgetJsonResponse.ts @@ -1,4 +1,22 @@ -import { ClientStatus } from "../../interfaces"; +/* + Spacebar: A FOSS re-implementation and extension of the Discord.com backend. + Copyright (C) 2023 Spacebar and Spacebar 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 . +*/ + +import { ClientStatus } from "@spacebar/util"; export interface GuildWidgetJsonResponse { id: string; diff --git a/src/util/schemas/responses/GuildWidgetSettingsResponse.ts b/src/util/schemas/responses/GuildWidgetSettingsResponse.ts index 3c6b45ce..6ffc771a 100644 --- a/src/util/schemas/responses/GuildWidgetSettingsResponse.ts +++ b/src/util/schemas/responses/GuildWidgetSettingsResponse.ts @@ -1,4 +1,22 @@ -import { Snowflake } from "../../util"; +/* + Spacebar: A FOSS re-implementation and extension of the Discord.com backend. + Copyright (C) 2023 Spacebar and Spacebar 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 . +*/ + +import { Snowflake } from "@spacebar/util"; export interface GuildWidgetSettingsResponse { enabled: boolean; diff --git a/src/util/schemas/responses/InstanceDomainsResponse.ts b/src/util/schemas/responses/InstanceDomainsResponse.ts index 60367492..0be3682b 100644 --- a/src/util/schemas/responses/InstanceDomainsResponse.ts +++ b/src/util/schemas/responses/InstanceDomainsResponse.ts @@ -1,3 +1,21 @@ +/* + Spacebar: A FOSS re-implementation and extension of the Discord.com backend. + Copyright (C) 2023 Spacebar and Spacebar 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 . +*/ + export interface InstanceDomainsResponse { cdn: string; gateway: string; diff --git a/src/util/schemas/responses/InstancePingResponse.ts b/src/util/schemas/responses/InstancePingResponse.ts index 5f1a9488..4ff3950a 100644 --- a/src/util/schemas/responses/InstancePingResponse.ts +++ b/src/util/schemas/responses/InstancePingResponse.ts @@ -1,3 +1,21 @@ +/* + Spacebar: A FOSS re-implementation and extension of the Discord.com backend. + Copyright (C) 2023 Spacebar and Spacebar 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 . +*/ + export interface InstancePingResponse { ping: "pong!"; instance: { diff --git a/src/util/schemas/responses/InstanceStatsResponse.ts b/src/util/schemas/responses/InstanceStatsResponse.ts index d24fd434..60541f02 100644 --- a/src/util/schemas/responses/InstanceStatsResponse.ts +++ b/src/util/schemas/responses/InstanceStatsResponse.ts @@ -1,3 +1,21 @@ +/* + Spacebar: A FOSS re-implementation and extension of the Discord.com backend. + Copyright (C) 2023 Spacebar and Spacebar 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 . +*/ + export interface InstanceStatsResponse { counts: { user: number; diff --git a/src/util/schemas/responses/LocationMetadataResponse.ts b/src/util/schemas/responses/LocationMetadataResponse.ts index 55337557..2a7ca9bf 100644 --- a/src/util/schemas/responses/LocationMetadataResponse.ts +++ b/src/util/schemas/responses/LocationMetadataResponse.ts @@ -1,3 +1,21 @@ +/* + Spacebar: A FOSS re-implementation and extension of the Discord.com backend. + Copyright (C) 2023 Spacebar and Spacebar 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 . +*/ + export interface LocationMetadataResponse { consent_required: boolean; country_code: string; diff --git a/src/util/schemas/responses/MemberJoinGuildResponse.ts b/src/util/schemas/responses/MemberJoinGuildResponse.ts index d7b39d10..b5c290b9 100644 --- a/src/util/schemas/responses/MemberJoinGuildResponse.ts +++ b/src/util/schemas/responses/MemberJoinGuildResponse.ts @@ -1,3 +1,21 @@ +/* + Spacebar: A FOSS re-implementation and extension of the Discord.com backend. + Copyright (C) 2023 Spacebar and Spacebar 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 . +*/ + import { Emoji, Guild, Role, Sticker } from "../../entities"; export interface MemberJoinGuildResponse { diff --git a/src/util/schemas/responses/OAuthAuthorizeResponse.ts b/src/util/schemas/responses/OAuthAuthorizeResponse.ts index 60d6d2e2..ba81f94c 100644 --- a/src/util/schemas/responses/OAuthAuthorizeResponse.ts +++ b/src/util/schemas/responses/OAuthAuthorizeResponse.ts @@ -1,3 +1,21 @@ +/* + Spacebar: A FOSS re-implementation and extension of the Discord.com backend. + Copyright (C) 2023 Spacebar and Spacebar 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 . +*/ + export interface OAuthAuthorizeResponse { location: string; } diff --git a/src/util/schemas/responses/Tenor.ts b/src/util/schemas/responses/Tenor.ts index 9dddf9d0..5af229e8 100644 --- a/src/util/schemas/responses/Tenor.ts +++ b/src/util/schemas/responses/Tenor.ts @@ -1,3 +1,21 @@ +/* + Spacebar: A FOSS re-implementation and extension of the Discord.com backend. + Copyright (C) 2023 Spacebar and Spacebar 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 . +*/ + export enum TenorMediaTypes { gif, mediumgif, diff --git a/src/util/schemas/responses/TokenResponse.ts b/src/util/schemas/responses/TokenResponse.ts index 7e93055a..bc136051 100644 --- a/src/util/schemas/responses/TokenResponse.ts +++ b/src/util/schemas/responses/TokenResponse.ts @@ -1,3 +1,21 @@ +/* + Spacebar: A FOSS re-implementation and extension of the Discord.com backend. + Copyright (C) 2023 Spacebar and Spacebar 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 . +*/ + import { BackupCode, UserSettings } from "../../entities"; export interface TokenResponse { diff --git a/src/util/schemas/responses/TypedResponses.ts b/src/util/schemas/responses/TypedResponses.ts index 4349b93c..8214ff7b 100644 --- a/src/util/schemas/responses/TypedResponses.ts +++ b/src/util/schemas/responses/TypedResponses.ts @@ -1,3 +1,21 @@ +/* + Spacebar: A FOSS re-implementation and extension of the Discord.com backend. + Copyright (C) 2023 Spacebar and Spacebar 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 . +*/ + import { GeneralConfiguration, LimitsConfiguration } from "../../config"; import { DmChannelDTO } from "../../dtos"; import { @@ -86,3 +104,10 @@ export type APIGuildVoiceRegion = GuildVoiceRegion[]; export type APILimitsConfiguration = LimitsConfiguration; export type APIStickerPackArray = StickerPack[]; + +export type APIConnectionsConfiguration = Record< + string, + { + enabled: boolean; + } +>; diff --git a/src/util/schemas/responses/UpdatesResponse.ts b/src/util/schemas/responses/UpdatesResponse.ts index 6b8566f4..d8770b4e 100644 --- a/src/util/schemas/responses/UpdatesResponse.ts +++ b/src/util/schemas/responses/UpdatesResponse.ts @@ -1,3 +1,21 @@ +/* + Spacebar: A FOSS re-implementation and extension of the Discord.com backend. + Copyright (C) 2023 Spacebar and Spacebar 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 . +*/ + export interface UpdatesResponse { name: string; pub_date: string; diff --git a/src/util/schemas/responses/UserNoteResponse.ts b/src/util/schemas/responses/UserNoteResponse.ts index b142811e..0bde99a3 100644 --- a/src/util/schemas/responses/UserNoteResponse.ts +++ b/src/util/schemas/responses/UserNoteResponse.ts @@ -1,3 +1,21 @@ +/* + Spacebar: A FOSS re-implementation and extension of the Discord.com backend. + Copyright (C) 2023 Spacebar and Spacebar 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 . +*/ + export interface UserNoteResponse { note: string; note_user_id: string; diff --git a/src/util/schemas/responses/UserProfileResponse.ts b/src/util/schemas/responses/UserProfileResponse.ts index eba7cbcc..7b63542e 100644 --- a/src/util/schemas/responses/UserProfileResponse.ts +++ b/src/util/schemas/responses/UserProfileResponse.ts @@ -1,4 +1,23 @@ +/* + Spacebar: A FOSS re-implementation and extension of the Discord.com backend. + Copyright (C) 2023 Spacebar and Spacebar 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 . +*/ + import { + Badge, Member, PublicConnectedAccount, PublicMember, @@ -34,4 +53,5 @@ export interface UserProfileResponse { user_profile: UserProfile; guild_member?: PublicMember; guild_member_profile?: PublicMemberProfile; + badges: Badge[]; } diff --git a/src/util/schemas/responses/UserRelationsResponse.ts b/src/util/schemas/responses/UserRelationsResponse.ts index e784cafb..808dd3d3 100644 --- a/src/util/schemas/responses/UserRelationsResponse.ts +++ b/src/util/schemas/responses/UserRelationsResponse.ts @@ -1,3 +1,20 @@ +/* + Spacebar: A FOSS re-implementation and extension of the Discord.com backend. + Copyright (C) 2023 Spacebar and Spacebar 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 . +*/ import { User } from "@spacebar/util"; export type UserRelationsResponse = (Pick & diff --git a/src/util/schemas/responses/UserRelationshipsResponse.ts b/src/util/schemas/responses/UserRelationshipsResponse.ts index dff2f118..115c45ae 100644 --- a/src/util/schemas/responses/UserRelationshipsResponse.ts +++ b/src/util/schemas/responses/UserRelationshipsResponse.ts @@ -1,3 +1,20 @@ +/* + Spacebar: A FOSS re-implementation and extension of the Discord.com backend. + Copyright (C) 2023 Spacebar and Spacebar 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 . +*/ import { PublicUser, RelationshipType } from "../../entities"; export interface UserRelationshipsResponse { diff --git a/src/util/schemas/responses/WebAuthnCreateResponse.ts b/src/util/schemas/responses/WebAuthnCreateResponse.ts index 9aa9e206..57386e6d 100644 --- a/src/util/schemas/responses/WebAuthnCreateResponse.ts +++ b/src/util/schemas/responses/WebAuthnCreateResponse.ts @@ -1,3 +1,20 @@ +/* + Spacebar: A FOSS re-implementation and extension of the Discord.com backend. + Copyright (C) 2023 Spacebar and Spacebar 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 . +*/ export interface WebAuthnCreateResponse { name: string; id: string; diff --git a/src/util/schemas/responses/WebhookCreateResponse.ts b/src/util/schemas/responses/WebhookCreateResponse.ts index ae142632..7226e617 100644 --- a/src/util/schemas/responses/WebhookCreateResponse.ts +++ b/src/util/schemas/responses/WebhookCreateResponse.ts @@ -1,3 +1,21 @@ +/* + Spacebar: A FOSS re-implementation and extension of the Discord.com backend. + Copyright (C) 2023 Spacebar and Spacebar 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 . +*/ + import { User, Webhook } from "../../entities"; export interface WebhookCreateResponse { diff --git a/src/util/schemas/responses/index.ts b/src/util/schemas/responses/index.ts index d8b7fd57..accb26f5 100644 --- a/src/util/schemas/responses/index.ts +++ b/src/util/schemas/responses/index.ts @@ -1,3 +1,21 @@ +/* + Spacebar: A FOSS re-implementation and extension of the Discord.com backend. + Copyright (C) 2023 Spacebar and Spacebar 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 . +*/ + export * from "./APIErrorOrCaptchaResponse"; export * from "./APIErrorResponse"; export * from "./BackupCodesChallengeResponse"; @@ -28,7 +46,7 @@ export * from "./TypedResponses"; export * from "./UpdatesResponse"; export * from "./UserNoteResponse"; export * from "./UserProfileResponse"; -export * from "./UserRelationshipsResponse"; export * from "./UserRelationsResponse"; +export * from "./UserRelationshipsResponse"; export * from "./WebAuthnCreateResponse"; export * from "./WebhookCreateResponse"; diff --git a/src/util/util/Constants.ts b/src/util/util/Constants.ts index 112b0cc4..a6caae00 100644 --- a/src/util/util/Constants.ts +++ b/src/util/util/Constants.ts @@ -1,17 +1,17 @@ /* Spacebar: A FOSS re-implementation and extension of the Discord.com backend. Copyright (C) 2023 Spacebar and Spacebar 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 . */ @@ -553,6 +553,8 @@ export const VerificationLevels = [ * * LOTTIE_ANIMATION_MAXIMUM_DIMENSIONS * * STICKER_FRAME_RATE_TOO_SMALL_OR_TOO_LARGE * * STICKER_ANIMATION_DURATION_MAXIMUM + * * AUTOMODERATOR_BLOCK + * * BULK_BAN_FAILED * * UNKNOWN_VOICE_STATE * @typedef {string} APIError */ @@ -1001,6 +1003,7 @@ export const DiscordApiErrors = { "Message was blocked by automatic moderation", 200000, ), + BULK_BAN_FAILED: new ApiError("Failed to ban users", 500000), //Other errors UNKNOWN_VOICE_STATE: new ApiError("Unknown Voice State", 10065, 404), diff --git a/src/util/util/Rights.ts b/src/util/util/Rights.ts index 90ebe242..56d0e28d 100644 --- a/src/util/util/Rights.ts +++ b/src/util/util/Rights.ts @@ -94,6 +94,7 @@ export class Rights extends BitField { 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) + CREATE_REGISTRATION_TOKENS: BitFlag(50), // can create registration tokens (/auth/generate-registration-tokens) }; any(permission: RightResolvable, checkOperator = true) { diff --git a/src/util/util/email/index.ts b/src/util/util/email/index.ts index 619cc5c3..e3382794 100644 --- a/src/util/util/email/index.ts +++ b/src/util/util/email/index.ts @@ -141,8 +141,9 @@ export const Email: { */ generateLink: async function (type, id, email) { const token = (await generateToken(id, email)) as string; + // puyodead1: this is set to api endpoint because the verification page is on the server since no clients have one, and not all 3rd party clients will have one const instanceUrl = - Config.get().general.frontPage || "http://localhost:3001"; + Config.get().api.endpointPublic || "http://localhost:3001"; const link = `${instanceUrl}/${type}#token=${token}`; return link; }, @@ -187,7 +188,9 @@ export const Email: { const message = { from: - Config.get().general.correspondenceEmail || "noreply@localhost", + Config.get().email.senderAddress || + Config.get().general.correspondenceEmail || + "noreply@localhost", to: email, subject, html, diff --git a/src/util/util/email/transports/SMTP.ts b/src/util/util/email/transports/SMTP.ts index 5b43a870..e3031943 100644 --- a/src/util/util/email/transports/SMTP.ts +++ b/src/util/util/email/transports/SMTP.ts @@ -27,9 +27,12 @@ export default async function () { if (!host || !port || secure === null || !username || !password) return console.error("[Email] SMTP has not been configured correctly."); - if (!Config.get().general.correspondenceEmail) + if ( + !Config.get().email.senderAddress && + !Config.get().general.correspondenceEmail + ) return console.error( - "[Email] Correspondence email has not been configured! This is used as the sender email address.", + '[Email] You have to configure either "email_senderAddress" or "general_correspondenceEmail" for emails to work. The configured value is used as the sender address.', ); // construct the transporter