diff --git a/assets/client_test/developers.html b/assets/client_test/developers.html new file mode 100644 index 0000000..59b3b12 --- /dev/null +++ b/assets/client_test/developers.html @@ -0,0 +1,43 @@ + + + + + + + + + + Fosscord Test Client Developer Portal + + + + +
+ + + + + + + diff --git a/assets/client_test/index.html b/assets/client_test/index.html new file mode 100644 index 0000000..a2e4039 --- /dev/null +++ b/assets/client_test/index.html @@ -0,0 +1,138 @@ + + + + + + + Fosscord Test Client + + + + + + + + + + + + + + + + + +
+ + + + + + + + diff --git a/assets/client_test/public/1f0bfc0865d324c2587920a7d80c609b.png b/assets/client_test/public/1f0bfc0865d324c2587920a7d80c609b.png new file mode 100644 index 0000000..9b92bd2 --- /dev/null +++ b/assets/client_test/public/1f0bfc0865d324c2587920a7d80c609b.png Binary files differ diff --git a/assets/client_test/public/3c6ccb83716d1e4fb91d3082f6b21d77.png b/assets/client_test/public/3c6ccb83716d1e4fb91d3082f6b21d77.png new file mode 100644 index 0000000..62c599a --- /dev/null +++ b/assets/client_test/public/3c6ccb83716d1e4fb91d3082f6b21d77.png Binary files differ diff --git a/assets/client_test/public/4c1b599b1ef5b9f1874fdb9933f3e03b.png b/assets/client_test/public/4c1b599b1ef5b9f1874fdb9933f3e03b.png new file mode 100644 index 0000000..bd7afef --- /dev/null +++ b/assets/client_test/public/4c1b599b1ef5b9f1874fdb9933f3e03b.png Binary files differ diff --git a/assets/client_test/public/6f26ddd1bf59740c536d2274bb834a05.png b/assets/client_test/public/6f26ddd1bf59740c536d2274bb834a05.png new file mode 100644 index 0000000..9f13790 --- /dev/null +++ b/assets/client_test/public/6f26ddd1bf59740c536d2274bb834a05.png Binary files differ diff --git a/assets/client_test/public/7c8f476123d28d103efe381543274c25.png b/assets/client_test/public/7c8f476123d28d103efe381543274c25.png new file mode 100644 index 0000000..3e8eeae --- /dev/null +++ b/assets/client_test/public/7c8f476123d28d103efe381543274c25.png Binary files differ diff --git a/assets/client_test/public/c09a43a372ba81e3018c3151d4ed4773.png b/assets/client_test/public/c09a43a372ba81e3018c3151d4ed4773.png new file mode 100644 index 0000000..67ee7bb --- /dev/null +++ b/assets/client_test/public/c09a43a372ba81e3018c3151d4ed4773.png Binary files differ diff --git a/assets/client_test/public/endpoints.json b/assets/client_test/public/endpoints.json new file mode 100644 index 0000000..8b0514c --- /dev/null +++ b/assets/client_test/public/endpoints.json @@ -0,0 +1,115 @@ +{ + "USER_CHANNELS": "/users/@me/channels", + "USER_ACTIVITY_STATISTICS": "/users/@me/activities/statistics/applications", + "ACTIVITIES": "/activities", + "LOBBIES": "/lobbies", + "LOBBY_SEARCH": "/lobbies/search", + "NETWORKING_TOKEN": "/networking/token", + "USER_GAMES_NOTIFICATIONS": "/users/@me/settings/game-notifications", + "USER_GAMES_NOTIFICATIONS_OVERRIDES": "/users/@me/settings/game-notifications/overrides", + "UNVERIFIED_APPLICATIONS": "/unverified-applications", + "UNVERIFIED_APPLICATIONS_ICONS": "/unverified-applications/icons", + "BULK_ACK": "/read-states/ack-bulk", + "GUILDS": "/guilds", + "CHANNELS": "/channels", + "TUTORIAL_INDICATORS": "/tutorial/indicators", + "TUTORIAL_INDICATORS_SUPPRESS": "/tutorial/indicators/suppress", + "USERS": "/users", + "ME": "/users/@me", + "DELETE_ACCOUNT": "/users/@me/delete", + "DISABLE_ACCOUNT": "/users/@me/disable", + "DEVICES": "/users/@me/devices", + "SETTINGS": "/users/@me/settings", + "SETTINGS_CONSENT": "/users/@me/consent", + "PHONE": "/users/@me/phone", + "VERIFY_PHONE": "/users/@me/phone/verify", + "VERIFY_PHONE_NEW": "/phone-verifications/verify", + "RESEND_PHONE": "/phone-verifications/resend", + "CONNECTIONS": "/users/@me/connections", + "CONNECTION_SYNC_CONTACTS": "/users/@me/connections/contacts/@me/external-friend-list-entries", + "NOTES": "/users/@me/notes", + "MENTIONS": "/users/@me/mentions", + "CAPTCHA": "/users/@me/captcha/verify", + "EXPERIMENTS": "/experiments", + "LOGIN": "/auth/login", + "LOGIN_MFA": "/auth/mfa/totp", + "LOGIN_SMS": "/auth/mfa/sms", + "LOGIN_SMS_SEND": "/auth/mfa/sms/send", + "REMOTE_AUTH_INITIALIZE": "/users/@me/remote-auth", + "REMOTE_AUTH_CANCEL": "/users/@me/remote-auth/cancel", + "REMOTE_AUTH_FINISH": "/users/@me/remote-auth/finish", + "LOGOUT": "/auth/logout", + "REGISTER": "/auth/register", + "REGISTER_PHONE": "/auth/register/phone", + "TRACK": "/science", + "SSO": "/sso", + "VERIFY": "/auth/verify", + "AUTHORIZE_IP": "/auth/authorize-ip", + "VERIFY_RESEND": "/auth/verify/resend", + "FORGOT_PASSWORD": "/auth/forgot", + "RESET_PASSWORD": "/auth/reset", + "ICE": "/voice/ice", + "REPORT": "/report", + "REPORT_V2": "/reports", + "REPORT_OPTIONS": "/report/options", + "INTEGRATIONS": "/integrations", + "GATEWAY": "/gateway", + "APPLICATIONS_DETECTABLE": "/applications/detectable", + "OAUTH2_AUTHORIZE": "/oauth2/authorize", + "OAUTH2_AUTHORIZE_WEBHOOK_CHANNELS": "/oauth2/authorize/webhook-channels", + "OAUTH2_CURRENT_AUTH": "/oauth2/@me", + "OAUTH2_TOKENS": "/oauth2/tokens", + "OAUTH2_WHITELIST_ACCEPT": "/oauth2/whitelist/accept", + "MFA_TOTP_ENABLE": "/users/@me/mfa/totp/enable", + "MFA_TOTP_DISABLE": "/users/@me/mfa/totp/disable", + "MFA_SMS_ENABLE": "/users/@me/mfa/sms/enable", + "MFA_SMS_DISABLE": "/users/@me/mfa/sms/disable", + "MFA_CODES": "/users/@me/mfa/codes", + "DISABLE_EMAIL_NOTIFICATIONS": "/users/disable-email-notifications", + "GUILD_PREMIUM_SUBSCRIPTION_COOLDOWN": "/users/@me/guilds/premium/subscriptions/cooldown", + "USER_GUILD_PREMIUM_SUBSCRIPTIONS": "/users/@me/guilds/premium/subscriptions", + "USER_PREMIUM_GUILD_SUBSCRIPTION_SLOTS": "/users/@me/guilds/premium/subscription-slots", + "BILLING_STRIPE_SETUP_INTENT_SECRET": "/users/@me/billing/stripe/setup-intents", + "BILLING_PAYMENT_SOURCES": "/users/@me/billing/payment-sources", + "BILLING_PAYMENTS": "/users/@me/billing/payments", + "BILLING_BRAINTREE_POPUP_BRIDGE": "/billing/braintree/popup-bridge", + "BILLING_BRAINTREE_POPUP_BRIDGE_CALLBACK": "/billing/braintree/popup-bridge/callback", + "BILLING_SUBSCRIPTIONS": "/users/@me/billing/subscriptions", + "BILLING_APPLY_APPLE_RECEIPT": "/billing/apple/apply-receipt", + "BILLING_INVOICE_PREVIEW": "/users/@me/billing/invoices/preview", + "USER_AGREEMENTS": "/users/@me/agreements", + "HANDOFF": "/auth/handoff", + "HANDOFF_EXCHANGE": "/auth/handoff/exchange", + "LIBRARY": "/users/@me/library", + "AUTH_CONSENT_REQUIRED": "/auth/consent-required", + "USER_HARVEST": "/users/@me/harvest", + "APPLICATION_BRANCHES": "/branches", + "APPLICATIONS_PUBLIC": "/applications/public", + "APPLICATIONS_TRENDING": "/applications/trending/global", + "STORE_PUBLISHED_LISTINGS_APPLICATIONS": "/store/published-listings/applications", + "STORE_PUBLISHED_LISTINGS_SKUS": "/store/published-listings/skus", + "ENTITLEMENTS_GIFTABLE": "/users/@me/entitlements/gifts", + "PROMOTIONS": "/promotions", + "PROMOTION_ACK": "/promotions/ack", + "HYPESQUAD_ONLINE": "/hypesquad/online", + "GIFS_SEARCH": "/gifs/search", + "GIFS_TRENDING": "/gifs/trending", + "GIFS_TRENDING_GIFS": "/gifs/trending-gifs", + "GIFS_SELECT": "/gifs/select", + "GIFS_SUGGEST": "/gifs/suggest", + "GIFS_TRENDING_SEARCH": "/gifs/trending-search", + "USER_GIFT_CODE_CREATE": "/users/@me/entitlements/gift-codes", + "USER_GIFT_CODES": "/users/@me/entitlements/gift-codes", + "GUILD_DISCOVERY": "/discoverable-guilds", + "GUILD_DISCOVERY_CATEGORIES": "/discovery/categories", + "GUILD_DISCOVERY_VALID_TERM": "/discovery/valid-term", + "USER_AFFINITIES": "/users/@me/affinities/users", + "GUILD_AFFINITIES": "/users/@me/affinities/guilds", + "XBOX_GAME_PASS_PROMOTION": "/promotions/xbox-game-pass", + "XBOX_GAME_PASS_PROMOTION_REDEEM": "/promotions/xbox-game-pass/redeem", + "FUNIMATION_PROMOTION": "/promotions/funimation", + "PARTNERS_CONNECTIONS": "/partners/connections", + "PARTNERS_APPLY": "/partners/apply", + "USER_STICKER_PACKS": "/users/@me/sticker-packs", + "INTERACTIONS": "/interactions" +} diff --git a/assets/client_test/public/features.json b/assets/client_test/public/features.json new file mode 100644 index 0000000..05a858a --- /dev/null +++ b/assets/client_test/public/features.json @@ -0,0 +1,26 @@ +[ + "ANIMATED_ICON", + "BANNER", + "COMMERCE", + "COMMUNITY", + "DISCOVERABLE", + "DISCOVERABLE_DISABLED", + "ENABLED_DISCOVERABLE_BEFORE", + "HUB", + "INVITE_SPLASH", + "MONETIZATION_ENABLED", + "MORE_EMOJI", + "MORE_STICKERS", + "NEWS", + "PARTNERED", + "PREVIEW_ENABLED", + "PRIVATE_THREADS", + "SEVEN_DAY_THREAD_ARCHIVE", + "THREE_DAY_THREAD_ARCHIVE", + "THREADS_ENABLED", + "TICKETED_EVENTS_ENABLED", + "VANITY_URL", + "VERIFIED", + "VIP_REGIONS", + "WELCOME_SCREEN_ENABLED" +] diff --git a/assets/client_test/public/fosscord-login.css b/assets/client_test/public/fosscord-login.css new file mode 100644 index 0000000..76cf806 --- /dev/null +++ b/assets/client_test/public/fosscord-login.css @@ -0,0 +1,68 @@ +/* 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 Fosscord!"; + 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/fosscord/fosscord/master/assets-rebrand/svg/Fosscord-Wordmark-Gradient.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/client_test/public/fosscord.css b/assets/client_test/public/fosscord.css new file mode 100644 index 0000000..2ee7b79 --- /dev/null +++ b/assets/client_test/public/fosscord.css @@ -0,0 +1,92 @@ +/* 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/fosscord/fosscord/master/assets-rebrand/svg/Fosscord-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/client_test/public/user.css b/assets/client_test/public/user.css new file mode 100644 index 0000000..a7e5c4f --- /dev/null +++ b/assets/client_test/public/user.css @@ -0,0 +1 @@ +/* Your custom CSS goes here, enjoy! */ \ No newline at end of file diff --git a/assets/client_test/verify.html b/assets/client_test/verify.html new file mode 100644 index 0000000..0de6fc6 --- /dev/null +++ b/assets/client_test/verify.html @@ -0,0 +1,58 @@ + + + + + + + + + + Fosscord Test Client + + + + +
+ + + + + + + + \ No newline at end of file diff --git a/assets/inline-plugins/.gitkeep b/assets/inline-plugins/.gitkeep new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/assets/inline-plugins/.gitkeep diff --git a/assets/openapi.json b/assets/openapi.json index b544528..26c330a 100644 --- a/assets/openapi.json +++ b/assets/openapi.json @@ -3767,9 +3767,7 @@ "additionalProperties": false }, "intents": { - "type": "number", - "properties": {}, - "additionalProperties": false + "type": "number" }, "presence": { "$ref": "#/components/schemas/ActivitySchema" @@ -3788,9 +3786,7 @@ "maxItems": 2, "type": "array", "items": { - "type": "number", - "properties": {}, - "additionalProperties": false + "type": "number" } }, "guild_subscriptions": { @@ -10872,6 +10868,9 @@ "$ref": "#/components/schemas/MessageSnapshot" } }, + "isWebhook": { + "type": "boolean" + }, "id": { "type": "string" } @@ -10881,6 +10880,7 @@ "embeds", "flags", "id", + "isWebhook", "mention_channels", "mention_roles", "mentions", diff --git a/assets/plugins/.gitkeep b/assets/plugins/.gitkeep new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/assets/plugins/.gitkeep diff --git a/assets/preload-plugins/.gitkeep b/assets/preload-plugins/.gitkeep new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/assets/preload-plugins/.gitkeep diff --git a/assets/preload-plugins/checkLocale.js b/assets/preload-plugins/checkLocale.js new file mode 100644 index 0000000..1b5e7b7 --- /dev/null +++ b/assets/preload-plugins/checkLocale.js @@ -0,0 +1,38 @@ +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 new file mode 100644 index 0000000..5b78ec8 --- /dev/null +++ b/assets/preload-plugins/oauth2.js @@ -0,0 +1,9 @@ +// 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/1276374a404452756f3c9cc2601508a5.png b/assets/public/1276374a404452756f3c9cc2601508a5.png deleted file mode 100644 index b9f7f62..0000000 --- a/assets/public/1276374a404452756f3c9cc2601508a5.png +++ /dev/null Binary files differ diff --git a/assets/public/1f0bfc0865d324c2587920a7d80c609b.png b/assets/public/1f0bfc0865d324c2587920a7d80c609b.png new file mode 100644 index 0000000..9b92bd2 --- /dev/null +++ b/assets/public/1f0bfc0865d324c2587920a7d80c609b.png Binary files differ diff --git a/assets/public/22341bdb500c7b63a93bbce957d1601e.png b/assets/public/22341bdb500c7b63a93bbce957d1601e.png deleted file mode 100644 index c8bf93d..0000000 --- a/assets/public/22341bdb500c7b63a93bbce957d1601e.png +++ /dev/null Binary files differ diff --git a/assets/public/2e46fe14586f8e95471c0917f56726b5.png b/assets/public/2e46fe14586f8e95471c0917f56726b5.png deleted file mode 100644 index bf747d7..0000000 --- a/assets/public/2e46fe14586f8e95471c0917f56726b5.png +++ /dev/null Binary files differ diff --git a/assets/public/3b70bb66089c60f8be5e214bf8574c9d.png b/assets/public/3b70bb66089c60f8be5e214bf8574c9d.png deleted file mode 100644 index c4f95d9..0000000 --- a/assets/public/3b70bb66089c60f8be5e214bf8574c9d.png +++ /dev/null Binary files differ diff --git a/assets/public/3c6ccb83716d1e4fb91d3082f6b21d77.png b/assets/public/3c6ccb83716d1e4fb91d3082f6b21d77.png new file mode 100644 index 0000000..62c599a --- /dev/null +++ b/assets/public/3c6ccb83716d1e4fb91d3082f6b21d77.png Binary files differ diff --git a/assets/public/4a8562cf00887030c416d3ec2d46385a.png b/assets/public/4a8562cf00887030c416d3ec2d46385a.png deleted file mode 100644 index 73426bc..0000000 --- a/assets/public/4a8562cf00887030c416d3ec2d46385a.png +++ /dev/null Binary files differ diff --git a/assets/public/4ab900144b0865430dc9be825c838faa.png b/assets/public/4ab900144b0865430dc9be825c838faa.png deleted file mode 100644 index f3ba032..0000000 --- a/assets/public/4ab900144b0865430dc9be825c838faa.png +++ /dev/null Binary files differ diff --git a/assets/public/4c1b599b1ef5b9f1874fdb9933f3e03b.png b/assets/public/4c1b599b1ef5b9f1874fdb9933f3e03b.png new file mode 100644 index 0000000..bd7afef --- /dev/null +++ b/assets/public/4c1b599b1ef5b9f1874fdb9933f3e03b.png Binary files differ diff --git a/assets/public/6f26ddd1bf59740c536d2274bb834a05.png b/assets/public/6f26ddd1bf59740c536d2274bb834a05.png new file mode 100644 index 0000000..9f13790 --- /dev/null +++ b/assets/public/6f26ddd1bf59740c536d2274bb834a05.png Binary files differ diff --git a/assets/public/7213ab6677377974697dfdfbaf5f6a6f.png b/assets/public/7213ab6677377974697dfdfbaf5f6a6f.png deleted file mode 100644 index f1fa9f0..0000000 --- a/assets/public/7213ab6677377974697dfdfbaf5f6a6f.png +++ /dev/null Binary files differ diff --git a/assets/public/7c8f476123d28d103efe381543274c25.png b/assets/public/7c8f476123d28d103efe381543274c25.png new file mode 100644 index 0000000..3e8eeae --- /dev/null +++ b/assets/public/7c8f476123d28d103efe381543274c25.png Binary files differ diff --git a/assets/public/904bf9f1b61f53ef4a3b7a893afeabe3.png b/assets/public/904bf9f1b61f53ef4a3b7a893afeabe3.png deleted file mode 100644 index 0cac967..0000000 --- a/assets/public/904bf9f1b61f53ef4a3b7a893afeabe3.png +++ /dev/null Binary files differ diff --git a/assets/public/9581acd31832465bdeaa5385b0e919a3.png b/assets/public/9581acd31832465bdeaa5385b0e919a3.png deleted file mode 100644 index 1026155..0000000 --- a/assets/public/9581acd31832465bdeaa5385b0e919a3.png +++ /dev/null Binary files differ diff --git a/assets/public/9b0bb198936784c45c72833cc426cc55.png b/assets/public/9b0bb198936784c45c72833cc426cc55.png deleted file mode 100644 index 367051c..0000000 --- a/assets/public/9b0bb198936784c45c72833cc426cc55.png +++ /dev/null Binary files differ diff --git a/assets/public/9d6ddb4e4d899a533a8cc617011351c9.png b/assets/public/9d6ddb4e4d899a533a8cc617011351c9.png deleted file mode 100644 index 740cdd2..0000000 --- a/assets/public/9d6ddb4e4d899a533a8cc617011351c9.png +++ /dev/null Binary files differ diff --git a/assets/public/a8a4727cf2dc2939bd3c657fad4463fa.png b/assets/public/a8a4727cf2dc2939bd3c657fad4463fa.png deleted file mode 100644 index 35f16cc..0000000 --- a/assets/public/a8a4727cf2dc2939bd3c657fad4463fa.png +++ /dev/null Binary files differ diff --git a/assets/public/c09a43a372ba81e3018c3151d4ed4773.png b/assets/public/c09a43a372ba81e3018c3151d4ed4773.png new file mode 100644 index 0000000..67ee7bb --- /dev/null +++ b/assets/public/c09a43a372ba81e3018c3151d4ed4773.png Binary files differ diff --git a/assets/public/d9977836b82058bf2f74eebd50edc095.png b/assets/public/d9977836b82058bf2f74eebd50edc095.png deleted file mode 100644 index bb73cd9..0000000 --- a/assets/public/d9977836b82058bf2f74eebd50edc095.png +++ /dev/null Binary files differ diff --git a/assets/public/fac7e78de9753d4a37083bba74c1d9ef.png b/assets/public/fac7e78de9753d4a37083bba74c1d9ef.png deleted file mode 100644 index 78b66c7..0000000 --- a/assets/public/fac7e78de9753d4a37083bba74c1d9ef.png +++ /dev/null Binary files differ diff --git a/assets/public/fosscord-login.css b/assets/public/fosscord-login.css new file mode 100644 index 0000000..76cf806 --- /dev/null +++ b/assets/public/fosscord-login.css @@ -0,0 +1,68 @@ +/* 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 Fosscord!"; + 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/fosscord/fosscord/master/assets-rebrand/svg/Fosscord-Wordmark-Gradient.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 new file mode 100644 index 0000000..2ee7b79 --- /dev/null +++ b/assets/public/fosscord.css @@ -0,0 +1,92 @@ +/* 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/fosscord/fosscord/master/assets-rebrand/svg/Fosscord-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/index.html b/assets/public/index.html deleted file mode 100644 index 3723cab..0000000 --- a/assets/public/index.html +++ /dev/null @@ -1,65 +0,0 @@ - - - - - - - - Spacebar Server - - - - - - - - - -
- Spacebar Logo - -

Welcome!

-

If you're viewing this page, that means you've successfully set up your very own Spacebar instance!

-

For information on how to configure your shiny new setup, you should visit our documentation

-

For information on how to connect and use your instance, click here

-
- - - \ No newline at end of file diff --git a/assets/public/user.css b/assets/public/user.css new file mode 100644 index 0000000..a7e5c4f --- /dev/null +++ b/assets/public/user.css @@ -0,0 +1 @@ +/* Your custom CSS goes here, enjoy! */ \ No newline at end of file diff --git a/assets/public/verify.html b/assets/public/verify.html deleted file mode 100644 index 83ce865..0000000 --- a/assets/public/verify.html +++ /dev/null @@ -1,292 +0,0 @@ - - - - - - - Spacebar Server - - - - - - - - - -
- Spacebar Logo - -
-

Verifying your email

-

Please wait...

-
-
- - - - diff --git a/assets/public/widget.html b/assets/public/widget.html deleted file mode 100644 index b72e1d9..0000000 --- a/assets/public/widget.html +++ /dev/null @@ -1,175 +0,0 @@ - - - - - - - - Spacebar Widget - - - - - - - - - - - -
-
- Spacebar Logo - - Unknown - users online - -
-
-
-

Online users

-
-
-
- - - \ No newline at end of file diff --git a/assets/publicold/1276374a404452756f3c9cc2601508a5.png b/assets/publicold/1276374a404452756f3c9cc2601508a5.png new file mode 100644 index 0000000..b9f7f62 --- /dev/null +++ b/assets/publicold/1276374a404452756f3c9cc2601508a5.png Binary files differ diff --git a/assets/publicold/22341bdb500c7b63a93bbce957d1601e.png b/assets/publicold/22341bdb500c7b63a93bbce957d1601e.png new file mode 100644 index 0000000..c8bf93d --- /dev/null +++ b/assets/publicold/22341bdb500c7b63a93bbce957d1601e.png Binary files differ diff --git a/assets/publicold/2e46fe14586f8e95471c0917f56726b5.png b/assets/publicold/2e46fe14586f8e95471c0917f56726b5.png new file mode 100644 index 0000000..bf747d7 --- /dev/null +++ b/assets/publicold/2e46fe14586f8e95471c0917f56726b5.png Binary files differ diff --git a/assets/publicold/3b70bb66089c60f8be5e214bf8574c9d.png b/assets/publicold/3b70bb66089c60f8be5e214bf8574c9d.png new file mode 100644 index 0000000..c4f95d9 --- /dev/null +++ b/assets/publicold/3b70bb66089c60f8be5e214bf8574c9d.png Binary files differ diff --git a/assets/publicold/4a8562cf00887030c416d3ec2d46385a.png b/assets/publicold/4a8562cf00887030c416d3ec2d46385a.png new file mode 100644 index 0000000..73426bc --- /dev/null +++ b/assets/publicold/4a8562cf00887030c416d3ec2d46385a.png Binary files differ diff --git a/assets/publicold/4ab900144b0865430dc9be825c838faa.png b/assets/publicold/4ab900144b0865430dc9be825c838faa.png new file mode 100644 index 0000000..f3ba032 --- /dev/null +++ b/assets/publicold/4ab900144b0865430dc9be825c838faa.png Binary files differ diff --git a/assets/publicold/7213ab6677377974697dfdfbaf5f6a6f.png b/assets/publicold/7213ab6677377974697dfdfbaf5f6a6f.png new file mode 100644 index 0000000..f1fa9f0 --- /dev/null +++ b/assets/publicold/7213ab6677377974697dfdfbaf5f6a6f.png Binary files differ diff --git a/assets/publicold/904bf9f1b61f53ef4a3b7a893afeabe3.png b/assets/publicold/904bf9f1b61f53ef4a3b7a893afeabe3.png new file mode 100644 index 0000000..0cac967 --- /dev/null +++ b/assets/publicold/904bf9f1b61f53ef4a3b7a893afeabe3.png Binary files differ diff --git a/assets/publicold/9581acd31832465bdeaa5385b0e919a3.png b/assets/publicold/9581acd31832465bdeaa5385b0e919a3.png new file mode 100644 index 0000000..1026155 --- /dev/null +++ b/assets/publicold/9581acd31832465bdeaa5385b0e919a3.png Binary files differ diff --git a/assets/publicold/9b0bb198936784c45c72833cc426cc55.png b/assets/publicold/9b0bb198936784c45c72833cc426cc55.png new file mode 100644 index 0000000..367051c --- /dev/null +++ b/assets/publicold/9b0bb198936784c45c72833cc426cc55.png Binary files differ diff --git a/assets/publicold/9d6ddb4e4d899a533a8cc617011351c9.png b/assets/publicold/9d6ddb4e4d899a533a8cc617011351c9.png new file mode 100644 index 0000000..740cdd2 --- /dev/null +++ b/assets/publicold/9d6ddb4e4d899a533a8cc617011351c9.png Binary files differ diff --git a/assets/publicold/a8a4727cf2dc2939bd3c657fad4463fa.png b/assets/publicold/a8a4727cf2dc2939bd3c657fad4463fa.png new file mode 100644 index 0000000..35f16cc --- /dev/null +++ b/assets/publicold/a8a4727cf2dc2939bd3c657fad4463fa.png Binary files differ diff --git a/assets/publicold/d9977836b82058bf2f74eebd50edc095.png b/assets/publicold/d9977836b82058bf2f74eebd50edc095.png new file mode 100644 index 0000000..bb73cd9 --- /dev/null +++ b/assets/publicold/d9977836b82058bf2f74eebd50edc095.png Binary files differ diff --git a/assets/publicold/endpoints.json b/assets/publicold/endpoints.json new file mode 100644 index 0000000..8b0514c --- /dev/null +++ b/assets/publicold/endpoints.json @@ -0,0 +1,115 @@ +{ + "USER_CHANNELS": "/users/@me/channels", + "USER_ACTIVITY_STATISTICS": "/users/@me/activities/statistics/applications", + "ACTIVITIES": "/activities", + "LOBBIES": "/lobbies", + "LOBBY_SEARCH": "/lobbies/search", + "NETWORKING_TOKEN": "/networking/token", + "USER_GAMES_NOTIFICATIONS": "/users/@me/settings/game-notifications", + "USER_GAMES_NOTIFICATIONS_OVERRIDES": "/users/@me/settings/game-notifications/overrides", + "UNVERIFIED_APPLICATIONS": "/unverified-applications", + "UNVERIFIED_APPLICATIONS_ICONS": "/unverified-applications/icons", + "BULK_ACK": "/read-states/ack-bulk", + "GUILDS": "/guilds", + "CHANNELS": "/channels", + "TUTORIAL_INDICATORS": "/tutorial/indicators", + "TUTORIAL_INDICATORS_SUPPRESS": "/tutorial/indicators/suppress", + "USERS": "/users", + "ME": "/users/@me", + "DELETE_ACCOUNT": "/users/@me/delete", + "DISABLE_ACCOUNT": "/users/@me/disable", + "DEVICES": "/users/@me/devices", + "SETTINGS": "/users/@me/settings", + "SETTINGS_CONSENT": "/users/@me/consent", + "PHONE": "/users/@me/phone", + "VERIFY_PHONE": "/users/@me/phone/verify", + "VERIFY_PHONE_NEW": "/phone-verifications/verify", + "RESEND_PHONE": "/phone-verifications/resend", + "CONNECTIONS": "/users/@me/connections", + "CONNECTION_SYNC_CONTACTS": "/users/@me/connections/contacts/@me/external-friend-list-entries", + "NOTES": "/users/@me/notes", + "MENTIONS": "/users/@me/mentions", + "CAPTCHA": "/users/@me/captcha/verify", + "EXPERIMENTS": "/experiments", + "LOGIN": "/auth/login", + "LOGIN_MFA": "/auth/mfa/totp", + "LOGIN_SMS": "/auth/mfa/sms", + "LOGIN_SMS_SEND": "/auth/mfa/sms/send", + "REMOTE_AUTH_INITIALIZE": "/users/@me/remote-auth", + "REMOTE_AUTH_CANCEL": "/users/@me/remote-auth/cancel", + "REMOTE_AUTH_FINISH": "/users/@me/remote-auth/finish", + "LOGOUT": "/auth/logout", + "REGISTER": "/auth/register", + "REGISTER_PHONE": "/auth/register/phone", + "TRACK": "/science", + "SSO": "/sso", + "VERIFY": "/auth/verify", + "AUTHORIZE_IP": "/auth/authorize-ip", + "VERIFY_RESEND": "/auth/verify/resend", + "FORGOT_PASSWORD": "/auth/forgot", + "RESET_PASSWORD": "/auth/reset", + "ICE": "/voice/ice", + "REPORT": "/report", + "REPORT_V2": "/reports", + "REPORT_OPTIONS": "/report/options", + "INTEGRATIONS": "/integrations", + "GATEWAY": "/gateway", + "APPLICATIONS_DETECTABLE": "/applications/detectable", + "OAUTH2_AUTHORIZE": "/oauth2/authorize", + "OAUTH2_AUTHORIZE_WEBHOOK_CHANNELS": "/oauth2/authorize/webhook-channels", + "OAUTH2_CURRENT_AUTH": "/oauth2/@me", + "OAUTH2_TOKENS": "/oauth2/tokens", + "OAUTH2_WHITELIST_ACCEPT": "/oauth2/whitelist/accept", + "MFA_TOTP_ENABLE": "/users/@me/mfa/totp/enable", + "MFA_TOTP_DISABLE": "/users/@me/mfa/totp/disable", + "MFA_SMS_ENABLE": "/users/@me/mfa/sms/enable", + "MFA_SMS_DISABLE": "/users/@me/mfa/sms/disable", + "MFA_CODES": "/users/@me/mfa/codes", + "DISABLE_EMAIL_NOTIFICATIONS": "/users/disable-email-notifications", + "GUILD_PREMIUM_SUBSCRIPTION_COOLDOWN": "/users/@me/guilds/premium/subscriptions/cooldown", + "USER_GUILD_PREMIUM_SUBSCRIPTIONS": "/users/@me/guilds/premium/subscriptions", + "USER_PREMIUM_GUILD_SUBSCRIPTION_SLOTS": "/users/@me/guilds/premium/subscription-slots", + "BILLING_STRIPE_SETUP_INTENT_SECRET": "/users/@me/billing/stripe/setup-intents", + "BILLING_PAYMENT_SOURCES": "/users/@me/billing/payment-sources", + "BILLING_PAYMENTS": "/users/@me/billing/payments", + "BILLING_BRAINTREE_POPUP_BRIDGE": "/billing/braintree/popup-bridge", + "BILLING_BRAINTREE_POPUP_BRIDGE_CALLBACK": "/billing/braintree/popup-bridge/callback", + "BILLING_SUBSCRIPTIONS": "/users/@me/billing/subscriptions", + "BILLING_APPLY_APPLE_RECEIPT": "/billing/apple/apply-receipt", + "BILLING_INVOICE_PREVIEW": "/users/@me/billing/invoices/preview", + "USER_AGREEMENTS": "/users/@me/agreements", + "HANDOFF": "/auth/handoff", + "HANDOFF_EXCHANGE": "/auth/handoff/exchange", + "LIBRARY": "/users/@me/library", + "AUTH_CONSENT_REQUIRED": "/auth/consent-required", + "USER_HARVEST": "/users/@me/harvest", + "APPLICATION_BRANCHES": "/branches", + "APPLICATIONS_PUBLIC": "/applications/public", + "APPLICATIONS_TRENDING": "/applications/trending/global", + "STORE_PUBLISHED_LISTINGS_APPLICATIONS": "/store/published-listings/applications", + "STORE_PUBLISHED_LISTINGS_SKUS": "/store/published-listings/skus", + "ENTITLEMENTS_GIFTABLE": "/users/@me/entitlements/gifts", + "PROMOTIONS": "/promotions", + "PROMOTION_ACK": "/promotions/ack", + "HYPESQUAD_ONLINE": "/hypesquad/online", + "GIFS_SEARCH": "/gifs/search", + "GIFS_TRENDING": "/gifs/trending", + "GIFS_TRENDING_GIFS": "/gifs/trending-gifs", + "GIFS_SELECT": "/gifs/select", + "GIFS_SUGGEST": "/gifs/suggest", + "GIFS_TRENDING_SEARCH": "/gifs/trending-search", + "USER_GIFT_CODE_CREATE": "/users/@me/entitlements/gift-codes", + "USER_GIFT_CODES": "/users/@me/entitlements/gift-codes", + "GUILD_DISCOVERY": "/discoverable-guilds", + "GUILD_DISCOVERY_CATEGORIES": "/discovery/categories", + "GUILD_DISCOVERY_VALID_TERM": "/discovery/valid-term", + "USER_AFFINITIES": "/users/@me/affinities/users", + "GUILD_AFFINITIES": "/users/@me/affinities/guilds", + "XBOX_GAME_PASS_PROMOTION": "/promotions/xbox-game-pass", + "XBOX_GAME_PASS_PROMOTION_REDEEM": "/promotions/xbox-game-pass/redeem", + "FUNIMATION_PROMOTION": "/promotions/funimation", + "PARTNERS_CONNECTIONS": "/partners/connections", + "PARTNERS_APPLY": "/partners/apply", + "USER_STICKER_PACKS": "/users/@me/sticker-packs", + "INTERACTIONS": "/interactions" +} diff --git a/assets/publicold/fac7e78de9753d4a37083bba74c1d9ef.png b/assets/publicold/fac7e78de9753d4a37083bba74c1d9ef.png new file mode 100644 index 0000000..78b66c7 --- /dev/null +++ b/assets/publicold/fac7e78de9753d4a37083bba74c1d9ef.png Binary files differ diff --git a/assets/publicold/features.json b/assets/publicold/features.json new file mode 100644 index 0000000..05a858a --- /dev/null +++ b/assets/publicold/features.json @@ -0,0 +1,26 @@ +[ + "ANIMATED_ICON", + "BANNER", + "COMMERCE", + "COMMUNITY", + "DISCOVERABLE", + "DISCOVERABLE_DISABLED", + "ENABLED_DISCOVERABLE_BEFORE", + "HUB", + "INVITE_SPLASH", + "MONETIZATION_ENABLED", + "MORE_EMOJI", + "MORE_STICKERS", + "NEWS", + "PARTNERED", + "PREVIEW_ENABLED", + "PRIVATE_THREADS", + "SEVEN_DAY_THREAD_ARCHIVE", + "THREE_DAY_THREAD_ARCHIVE", + "THREADS_ENABLED", + "TICKETED_EVENTS_ENABLED", + "VANITY_URL", + "VERIFIED", + "VIP_REGIONS", + "WELCOME_SCREEN_ENABLED" +] diff --git a/assets/publicold/index.html b/assets/publicold/index.html new file mode 100644 index 0000000..3723cab --- /dev/null +++ b/assets/publicold/index.html @@ -0,0 +1,65 @@ + + + + + + + + Spacebar Server + + + + + + + + + +
+ Spacebar Logo + +

Welcome!

+

If you're viewing this page, that means you've successfully set up your very own Spacebar instance!

+

For information on how to configure your shiny new setup, you should visit our documentation

+

For information on how to connect and use your instance, click here

+
+ + + \ No newline at end of file diff --git a/assets/publicold/verify.html b/assets/publicold/verify.html new file mode 100644 index 0000000..83ce865 --- /dev/null +++ b/assets/publicold/verify.html @@ -0,0 +1,292 @@ + + + + + + + Spacebar Server + + + + + + + + + +
+ Spacebar Logo + +
+

Verifying your email

+

Please wait...

+
+
+ + + + diff --git a/assets/publicold/widget.html b/assets/publicold/widget.html new file mode 100644 index 0000000..b72e1d9 --- /dev/null +++ b/assets/publicold/widget.html @@ -0,0 +1,175 @@ + + + + + + + + Spacebar Widget + + + + + + + + + + + +
+
+ Spacebar Logo + + Unknown + users online + +
+
+
+

Online users

+
+
+
+ + + \ No newline at end of file diff --git a/assets/schemas.json b/assets/schemas.json index 3d4c30c..89841e8 100644 --- a/assets/schemas.json +++ b/assets/schemas.json @@ -3993,9 +3993,7 @@ "additionalProperties": false }, "intents": { - "type": "number", - "properties": {}, - "additionalProperties": false + "type": "bigint" }, "presence": { "$ref": "#/definitions/ActivitySchema" @@ -4014,9 +4012,7 @@ "maxItems": 2, "type": "array", "items": { - "type": "number", - "properties": {}, - "additionalProperties": false + "type": "bigint" } }, "guild_subscriptions": { @@ -11552,6 +11548,9 @@ "$ref": "#/definitions/MessageSnapshot" } }, + "isWebhook": { + "type": "boolean" + }, "id": { "type": "string" } @@ -11562,6 +11561,7 @@ "embeds", "flags", "id", + "isWebhook", "mention_channels", "mention_roles", "mentions", diff --git a/assets/widget/banner1.png b/assets/widget/banner1.png new file mode 100644 index 0000000..ed9bd5c --- /dev/null +++ b/assets/widget/banner1.png Binary files differ diff --git a/assets/widget/banner2.png b/assets/widget/banner2.png new file mode 100644 index 0000000..90d3713 --- /dev/null +++ b/assets/widget/banner2.png Binary files differ diff --git a/assets/widget/banner3.png b/assets/widget/banner3.png new file mode 100644 index 0000000..2235189 --- /dev/null +++ b/assets/widget/banner3.png Binary files differ diff --git a/assets/widget/banner4.png b/assets/widget/banner4.png new file mode 100644 index 0000000..e6bd7b6 --- /dev/null +++ b/assets/widget/banner4.png Binary files differ diff --git a/assets/widget/shield.png b/assets/widget/shield.png new file mode 100644 index 0000000..30277db --- /dev/null +++ b/assets/widget/shield.png Binary files differ diff --git a/package-lock.json b/package-lock.json index 659cd6a..5924712 100644 --- a/package-lock.json +++ b/package-lock.json @@ -43,11 +43,13 @@ "multer": "^2.1.1", "murmurhash-js": "^1.0.0", "node-2fa": "^2.0.3", + "node-fetch": "^3.3.2", "pg": "^8.21.0", "pg-query-stream": "^4.15.0", "picocolors": "^1.1.1", "probe-image-size": "^7.3.0", "prom-client": "^15.1.3", + "proxy-agent": "^8.0.2", "reflect-metadata": "^0.2.2", "tslib": "^2.8.1", "typeorm": "^0.3.30", @@ -2195,6 +2197,18 @@ "node": ">=12.0.0" } }, + "node_modules/ast-types": { + "version": "0.13.4", + "resolved": "https://registry.npmjs.org/ast-types/-/ast-types-0.13.4.tgz", + "integrity": "sha512-x1FCFnFifvYDDzTaLII71vG5uvDwgtmDTEVWAxrgeiR8VjMONcCXJx7E+USjDtHlwFmt9MysbqgF9b9Vjr6w+w==", + "license": "MIT", + "dependencies": { + "tslib": "^2.0.1" + }, + "engines": { + "node": ">=4" + } + }, "node_modules/asynckit": { "version": "0.4.0", "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", @@ -2306,6 +2320,15 @@ "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", "license": "MIT" }, + "node_modules/basic-ftp": { + "version": "5.3.1", + "resolved": "https://registry.npmjs.org/basic-ftp/-/basic-ftp-5.3.1.tgz", + "integrity": "sha512-bopVNp6ugyA150DDuZfPFdt1KZ5a94ZDiwX4hMgZDzF+GttD80lEy8kj98kbyhLXnPvhtIo93mdnLIjpCAeeOw==", + "license": "MIT", + "engines": { + "node": ">=10.0.0" + } + }, "node_modules/bcrypt": { "version": "6.0.0", "resolved": "https://registry.npmjs.org/bcrypt/-/bcrypt-6.0.0.tgz", @@ -2894,6 +2917,15 @@ "url": "https://github.com/sponsors/fb55" } }, + "node_modules/data-uri-to-buffer": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/data-uri-to-buffer/-/data-uri-to-buffer-4.0.1.tgz", + "integrity": "sha512-0R9ikRb668HB7QDxT1vkpuUBtqc53YyAwMwGeUFKRojY/NWKvdZ+9UYtRfGmhqNbRkTSVpMbmyhXipFFv2cb/A==", + "license": "MIT", + "engines": { + "node": ">= 12" + } + }, "node_modules/dayjs": { "version": "1.11.20", "resolved": "https://registry.npmjs.org/dayjs/-/dayjs-1.11.20.tgz", @@ -2965,6 +2997,23 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/degenerator": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/degenerator/-/degenerator-7.0.1.tgz", + "integrity": "sha512-ABErK0IefDSyHjlPH7WUEenIAX2rPPnrDcDM+TS3z3+zu9TfyKKi07BQM+8rmxpdE2y1v5fjjdoAS/x4D2U60w==", + "license": "MIT", + "dependencies": { + "ast-types": "^0.13.4", + "escodegen": "^2.1.0", + "esprima": "^4.0.1" + }, + "engines": { + "node": ">= 20" + }, + "peerDependencies": { + "quickjs-wasi": "^2.2.0" + } + }, "node_modules/delayed-stream": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", @@ -3254,6 +3303,27 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/escodegen": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/escodegen/-/escodegen-2.1.0.tgz", + "integrity": "sha512-2NlIDTwUWJN0mRPQOdtQBzbUHvdGY2P1VXSyU83Q3xKxM7WHX2Ql8dKq782Q9TgQUNOLEzEYu9bzLNj1q88I5w==", + "license": "BSD-2-Clause", + "dependencies": { + "esprima": "^4.0.1", + "estraverse": "^5.2.0", + "esutils": "^2.0.2" + }, + "bin": { + "escodegen": "bin/escodegen.js", + "esgenerate": "bin/esgenerate.js" + }, + "engines": { + "node": ">=6.0" + }, + "optionalDependencies": { + "source-map": "~0.6.1" + } + }, "node_modules/eslint": { "version": "9.39.4", "resolved": "https://registry.npmjs.org/eslint/-/eslint-9.39.4.tgz", @@ -3474,6 +3544,19 @@ "url": "https://opencollective.com/eslint" } }, + "node_modules/esprima": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz", + "integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==", + "license": "BSD-2-Clause", + "bin": { + "esparse": "bin/esparse.js", + "esvalidate": "bin/esvalidate.js" + }, + "engines": { + "node": ">=4" + } + }, "node_modules/esquery": { "version": "1.7.0", "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.7.0.tgz", @@ -3504,7 +3587,6 @@ "version": "5.3.0", "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz", "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==", - "dev": true, "license": "BSD-2-Clause", "engines": { "node": ">=4.0" @@ -3514,7 +3596,6 @@ "version": "2.0.3", "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz", "integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==", - "dev": true, "license": "BSD-2-Clause", "engines": { "node": ">=0.10.0" @@ -3642,6 +3723,29 @@ "url": "https://patreon.com/timotejroiko" } }, + "node_modules/fetch-blob": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/fetch-blob/-/fetch-blob-3.2.0.tgz", + "integrity": "sha512-7yAQpD2UMJzLi1Dqv7qFYnPbaPx7ZfFK6PiIxQ4PfkGPyNyl2Ugx+a/umUonmKqjhM4DnfbMvdX6otXq83soQQ==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/jimmywarting" + }, + { + "type": "paypal", + "url": "https://paypal.me/jimmywarting" + } + ], + "license": "MIT", + "dependencies": { + "node-domexception": "^1.0.0", + "web-streams-polyfill": "^3.0.3" + }, + "engines": { + "node": "^12.20 || >= 14.13" + } + }, "node_modules/fido2-lib": { "version": "3.5.9", "resolved": "https://registry.npmjs.org/fido2-lib/-/fido2-lib-3.5.9.tgz", @@ -3863,6 +3967,18 @@ "node": ">= 0.6" } }, + "node_modules/formdata-polyfill": { + "version": "4.0.10", + "resolved": "https://registry.npmjs.org/formdata-polyfill/-/formdata-polyfill-4.0.10.tgz", + "integrity": "sha512-buewHzMvYL29jdeQTVILecSaZKnt/RJWjoZCF5OW60Z67/GmSLBkOFM7qh1PI3zFNtJbaZL5eQu1vLfazOwj4g==", + "license": "MIT", + "dependencies": { + "fetch-blob": "^3.1.2" + }, + "engines": { + "node": ">=12.20.0" + } + }, "node_modules/forwarded": { "version": "0.2.0", "resolved": "https://registry.npmjs.org/forwarded/-/forwarded-0.2.0.tgz", @@ -3964,6 +4080,29 @@ "node": ">= 0.4" } }, + "node_modules/get-uri": { + "version": "8.0.1", + "resolved": "https://registry.npmjs.org/get-uri/-/get-uri-8.0.1.tgz", + "integrity": "sha512-/5N/P4Lrh0p/mDwlDRi7Y1+P2o/OyzZI3l6Iz1Ov6XXwwm1y3RlZLuo3gVgML99djrEDtV980bBxSuOeHLk8ww==", + "license": "MIT", + "dependencies": { + "basic-ftp": "^5.3.1", + "data-uri-to-buffer": "8.0.0", + "debug": "^4.3.4" + }, + "engines": { + "node": ">= 20" + } + }, + "node_modules/get-uri/node_modules/data-uri-to-buffer": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/data-uri-to-buffer/-/data-uri-to-buffer-8.0.0.tgz", + "integrity": "sha512-6UHfyCux51b8PTGDgveqtz1tvphBku5DrMKKJbFAZAJOI2zsjDpDoYE1+QGj7FOMS4BdTFNJsJiR3zEB0xH0yQ==", + "license": "MIT", + "engines": { + "node": ">= 20" + } + }, "node_modules/gifwrap": { "version": "0.10.1", "resolved": "https://registry.npmjs.org/gifwrap/-/gifwrap-0.10.1.tgz", @@ -4183,6 +4322,29 @@ "url": "https://opencollective.com/express" } }, + "node_modules/http-proxy-agent": { + "version": "9.1.0", + "resolved": "https://registry.npmjs.org/http-proxy-agent/-/http-proxy-agent-9.1.0.tgz", + "integrity": "sha512-2NxoveTT58mjYT4n3RPTEfCZGLMbidoO8XEieXfpSYxu+PQJ1qpx4ypwH6N+uF9twBPIvRRgvkvW5HUTYWENig==", + "license": "MIT", + "dependencies": { + "agent-base": "9.0.0", + "debug": "^4.3.4", + "proxy-agent-negotiate": "1.1.0" + }, + "engines": { + "node": ">= 20" + } + }, + "node_modules/http-proxy-agent/node_modules/agent-base": { + "version": "9.0.0", + "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-9.0.0.tgz", + "integrity": "sha512-TQf59BsZnytt8GdJKLPfUZ54g/iaUL2OWDSFCCvMOhsHduDQxO8xC4PNeyIkVcA5KwL2phPSv0douC0fgWzmnA==", + "license": "MIT", + "engines": { + "node": ">= 20" + } + }, "node_modules/https-proxy-agent": { "version": "5.0.1", "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-5.0.1.tgz", @@ -4361,6 +4523,15 @@ "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==", "license": "ISC" }, + "node_modules/ip-address": { + "version": "10.2.0", + "resolved": "https://registry.npmjs.org/ip-address/-/ip-address-10.2.0.tgz", + "integrity": "sha512-/+S6j4E9AHvW9SWMSEY9Xfy66O5PWvVEJ08O0y5JGyEKQpojb0K0GKpz/v5HJ/G0vi3D2sjGK78119oXZeE0qA==", + "license": "MIT", + "engines": { + "node": ">= 12" + } + }, "node_modules/ipaddr.js": { "version": "1.9.1", "resolved": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-1.9.1.tgz", @@ -5111,6 +5282,15 @@ "node": ">= 0.6" } }, + "node_modules/netmask": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/netmask/-/netmask-2.1.1.tgz", + "integrity": "sha512-eonl3sLUha+S1GzTPxychyhnUzKyeQkZ7jLjKrBagJgPla13F+uQ71HgpFefyHgqrjEbCPkDArxYsjY8/+gLKA==", + "license": "MIT", + "engines": { + "node": ">= 0.4.0" + } + }, "node_modules/node-2fa": { "version": "2.0.3", "resolved": "https://registry.npmjs.org/node-2fa/-/node-2fa-2.0.3.tgz", @@ -5132,6 +5312,44 @@ "node": "^18 || ^20 || >= 21" } }, + "node_modules/node-domexception": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/node-domexception/-/node-domexception-1.0.0.tgz", + "integrity": "sha512-/jKZoMpw0F8GRwl4/eLROPA3cfcXtLApP0QzLmUT/HuPCZWyB7IY9ZrMeKw2O/nFIqPQB3PVM9aYm0F312AXDQ==", + "deprecated": "Use your platform's native DOMException instead", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/jimmywarting" + }, + { + "type": "github", + "url": "https://paypal.me/jimmywarting" + } + ], + "license": "MIT", + "engines": { + "node": ">=10.5.0" + } + }, + "node_modules/node-fetch": { + "version": "3.3.2", + "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-3.3.2.tgz", + "integrity": "sha512-dRB78srN/l6gqWulah9SrxeYnxeddIG30+GOqK/9OlLVyLg3HPnr6SqOWTWOXKRwC2eGYCkZ59NNuSgvSrpgOA==", + "license": "MIT", + "dependencies": { + "data-uri-to-buffer": "^4.0.0", + "fetch-blob": "^3.1.4", + "formdata-polyfill": "^4.0.10" + }, + "engines": { + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/node-fetch" + } + }, "node_modules/node-gyp-build": { "version": "4.8.4", "resolved": "https://registry.npmjs.org/node-gyp-build/-/node-gyp-build-4.8.4.tgz", @@ -5330,6 +5548,64 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/pac-proxy-agent": { + "version": "9.1.0", + "resolved": "https://registry.npmjs.org/pac-proxy-agent/-/pac-proxy-agent-9.1.0.tgz", + "integrity": "sha512-1aU+1mpj3DrQPfo3gh+3Gap3G5x+axnMx1P/y0ZF2ch7kb2meyOCAH8K2k9d27ROsTE7TnAerzxqF9aon2jqnA==", + "license": "MIT", + "dependencies": { + "agent-base": "9.0.0", + "debug": "^4.3.4", + "get-uri": "8.0.1", + "http-proxy-agent": "9.1.0", + "https-proxy-agent": "9.1.0", + "pac-resolver": "9.0.1", + "quickjs-wasi": "^2.2.0", + "socks-proxy-agent": "10.1.0" + }, + "engines": { + "node": ">= 20" + } + }, + "node_modules/pac-proxy-agent/node_modules/agent-base": { + "version": "9.0.0", + "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-9.0.0.tgz", + "integrity": "sha512-TQf59BsZnytt8GdJKLPfUZ54g/iaUL2OWDSFCCvMOhsHduDQxO8xC4PNeyIkVcA5KwL2phPSv0douC0fgWzmnA==", + "license": "MIT", + "engines": { + "node": ">= 20" + } + }, + "node_modules/pac-proxy-agent/node_modules/https-proxy-agent": { + "version": "9.1.0", + "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-9.1.0.tgz", + "integrity": "sha512-ag87y7cJJ9/3+GxFr8Oy4O5faDsGRGnBGsJj/YjOSsSx/5eadKLYTMPlzuR6obgoCDDm0abAAZitXXQkMOPSpA==", + "license": "MIT", + "dependencies": { + "agent-base": "9.0.0", + "debug": "^4.3.4", + "proxy-agent-negotiate": "1.1.0" + }, + "engines": { + "node": ">= 20" + } + }, + "node_modules/pac-resolver": { + "version": "9.0.1", + "resolved": "https://registry.npmjs.org/pac-resolver/-/pac-resolver-9.0.1.tgz", + "integrity": "sha512-lJbS008tmkj08VhoM8Hzuv/VE5tK9MS0OIQ/7+s0lIF+BYhiQWFYzkSpML7lXs9iBu2jfmzBTLzhe9n6BX+dYw==", + "license": "MIT", + "dependencies": { + "degenerator": "7.0.1", + "netmask": "^2.0.2" + }, + "engines": { + "node": ">= 20" + }, + "peerDependencies": { + "quickjs-wasi": "^2.2.0" + } + }, "node_modules/package-json-from-dist": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/package-json-from-dist/-/package-json-from-dist-1.0.1.tgz", @@ -5918,12 +6194,79 @@ "node": ">= 0.10" } }, + "node_modules/proxy-agent": { + "version": "8.0.2", + "resolved": "https://registry.npmjs.org/proxy-agent/-/proxy-agent-8.0.2.tgz", + "integrity": "sha512-idLLRewuemWd7GH/BDJzGiB0dWGfT2SQs3jy6NtZtGWU9uPTTSdeC1/cdbqLwgzhfv027daGFuXX426e2Eg20A==", + "license": "MIT", + "dependencies": { + "agent-base": "9.0.0", + "debug": "^4.3.4", + "http-proxy-agent": "9.1.0", + "https-proxy-agent": "9.1.0", + "lru-cache": "^7.14.1", + "pac-proxy-agent": "9.1.0", + "proxy-from-env": "^2.0.0", + "socks-proxy-agent": "10.1.0" + }, + "engines": { + "node": ">= 20" + } + }, + "node_modules/proxy-agent-negotiate": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/proxy-agent-negotiate/-/proxy-agent-negotiate-1.1.0.tgz", + "integrity": "sha512-N8IBcM3UgCVzz2L2Lqv8DVntDnnC8/hiV4nEDUPkqq72TPUgYWjQc+bdZlBPZK9LzPAvOY//gAt0S0DApoOXWQ==", + "license": "MIT", + "engines": { + "node": ">= 20" + }, + "peerDependencies": { + "kerberos": "^2.0.0" + }, + "peerDependenciesMeta": { + "kerberos": { + "optional": true + } + } + }, + "node_modules/proxy-agent/node_modules/agent-base": { + "version": "9.0.0", + "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-9.0.0.tgz", + "integrity": "sha512-TQf59BsZnytt8GdJKLPfUZ54g/iaUL2OWDSFCCvMOhsHduDQxO8xC4PNeyIkVcA5KwL2phPSv0douC0fgWzmnA==", + "license": "MIT", + "engines": { + "node": ">= 20" + } + }, + "node_modules/proxy-agent/node_modules/https-proxy-agent": { + "version": "9.1.0", + "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-9.1.0.tgz", + "integrity": "sha512-ag87y7cJJ9/3+GxFr8Oy4O5faDsGRGnBGsJj/YjOSsSx/5eadKLYTMPlzuR6obgoCDDm0abAAZitXXQkMOPSpA==", + "license": "MIT", + "dependencies": { + "agent-base": "9.0.0", + "debug": "^4.3.4", + "proxy-agent-negotiate": "1.1.0" + }, + "engines": { + "node": ">= 20" + } + }, + "node_modules/proxy-agent/node_modules/lru-cache": { + "version": "7.18.3", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-7.18.3.tgz", + "integrity": "sha512-jumlc0BIUrS3qJGgIkWZsyfAM7NCWiBcCDhnd+3NNM5KbBmLTgHVfWBcg6W+rLUsIpzpERPsvwUP7CckAQSOoA==", + "license": "ISC", + "engines": { + "node": ">=12" + } + }, "node_modules/proxy-from-env": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/proxy-from-env/-/proxy-from-env-2.1.0.tgz", "integrity": "sha512-cJ+oHTW1VAEa8cJslgmUZrc+sjRKgAKl3Zyse6+PV38hZe/V6Z14TbCuXcan9F9ghlz4QrFr2c92TNF82UkYHA==", "license": "MIT", - "optional": true, "engines": { "node": ">=10" } @@ -5980,6 +6323,12 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/quickjs-wasi": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/quickjs-wasi/-/quickjs-wasi-2.2.0.tgz", + "integrity": "sha512-zQxXmQMrEoD3S+jQdYsloq4qAuaxKFHZj6hHqOYGwB2iQZH+q9e/lf5zQPXCKOk0WJuAjzRFbO4KwHIp2D05Iw==", + "license": "MIT" + }, "node_modules/randombytes": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/randombytes/-/randombytes-2.1.0.tgz", @@ -6367,6 +6716,63 @@ "node": ">=6" } }, + "node_modules/smart-buffer": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/smart-buffer/-/smart-buffer-4.2.0.tgz", + "integrity": "sha512-94hK0Hh8rPqQl2xXc3HsaBoOXKV20MToPkcXvwbISWLEs+64sBq5kFgn2kJDHb1Pry9yrP0dxrCI9RRci7RXKg==", + "license": "MIT", + "engines": { + "node": ">= 6.0.0", + "npm": ">= 3.0.0" + } + }, + "node_modules/socks": { + "version": "2.8.9", + "resolved": "https://registry.npmjs.org/socks/-/socks-2.8.9.tgz", + "integrity": "sha512-LJhUYUvItdQ0LkJTmPeaEObWXAqFyfmP85x0tch/ez9cahmhlBBLbIqDFnvBnUJGagb0JbIQrkBs1wJ+yRYpEw==", + "license": "MIT", + "dependencies": { + "ip-address": "^10.1.1", + "smart-buffer": "^4.2.0" + }, + "engines": { + "node": ">= 10.0.0", + "npm": ">= 3.0.0" + } + }, + "node_modules/socks-proxy-agent": { + "version": "10.1.0", + "resolved": "https://registry.npmjs.org/socks-proxy-agent/-/socks-proxy-agent-10.1.0.tgz", + "integrity": "sha512-WlMj/67cEJ6MDI1OcsnjuYKDNDoyPCCYZ249kuuXPiMDw9F8PXkVaQ7YWu3siTydfQ/4BEZcvGzu+aYvz7dDCQ==", + "license": "MIT", + "dependencies": { + "agent-base": "9.0.0", + "debug": "^4.3.4", + "socks": "^2.8.3" + }, + "engines": { + "node": ">= 20" + } + }, + "node_modules/socks-proxy-agent/node_modules/agent-base": { + "version": "9.0.0", + "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-9.0.0.tgz", + "integrity": "sha512-TQf59BsZnytt8GdJKLPfUZ54g/iaUL2OWDSFCCvMOhsHduDQxO8xC4PNeyIkVcA5KwL2phPSv0douC0fgWzmnA==", + "license": "MIT", + "engines": { + "node": ">= 20" + } + }, + "node_modules/source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "license": "BSD-3-Clause", + "optional": true, + "engines": { + "node": ">=0.10.0" + } + }, "node_modules/split2": { "version": "4.2.0", "resolved": "https://registry.npmjs.org/split2/-/split2-4.2.0.tgz", @@ -7343,6 +7749,15 @@ "node": ">=6.0" } }, + "node_modules/web-streams-polyfill": { + "version": "3.3.3", + "resolved": "https://registry.npmjs.org/web-streams-polyfill/-/web-streams-polyfill-3.3.3.tgz", + "integrity": "sha512-d2JWLCivmZYTSIoge9MsgFCZrt571BikcWGYkjC1khllbTeDlGqZ2D8vD8E/lJa8WGWbb7Plm8/XJYV7IJHZZw==", + "license": "MIT", + "engines": { + "node": ">= 8" + } + }, "node_modules/webcrypto-core": { "version": "1.9.2", "resolved": "https://registry.npmjs.org/webcrypto-core/-/webcrypto-core-1.9.2.tgz", diff --git a/package.json b/package.json index f20e31d..20149ea 100644 --- a/package.json +++ b/package.json @@ -111,11 +111,13 @@ "multer": "^2.1.1", "murmurhash-js": "^1.0.0", "node-2fa": "^2.0.3", + "node-fetch": "^3.3.2", "pg": "^8.21.0", "pg-query-stream": "^4.15.0", "picocolors": "^1.1.1", "probe-image-size": "^7.3.0", "prom-client": "^15.1.3", + "proxy-agent": "^8.0.2", "reflect-metadata": "^0.2.2", "tslib": "^2.8.1", "typeorm": "^0.3.30", diff --git a/src/api/Server.ts b/src/api/Server.ts index 9e4bb93..3627e71 100644 --- a/src/api/Server.ts +++ b/src/api/Server.ts @@ -17,7 +17,7 @@ */ import path from "node:path"; -import { Request, Response, Router } from "express"; +import express, { Request, Response, Router } from "express"; import morgan from "morgan"; import { Server, ServerOptions } from "lambert-server"; import { red } from "picocolors"; @@ -25,10 +25,14 @@ import { Authentication, CORS, ImageProxy, BodyParser, ErrorHandler, initRateLimits, initTranslation } from "./middlewares"; import { initInstance } from "./util/handlers/Instance"; import { route } from "./util"; +import fs from "node:fs"; import { ProcessLifecycle } from "../util/util/ProcessLifecycle"; import { Monitoring } from "../util/monitoring/Monitoring"; import { BcryptWorkerPool } from "../util/util/workers/bcrypt/BcryptWorkerPool"; +import { applyEnv, applyPlugins } from "./middlewares/TestClient"; +import fetch, { Response as FetchResponse, Headers } from "node-fetch"; +const ASSET_FOLDER_PATH = path.join(__dirname, "..", "..", "assets"); const ASSETS_FOLDER = path.join(__dirname, "..", "..", "assets"); const PUBLIC_ASSETS_FOLDER = path.join(ASSETS_FOLDER, "public"); @@ -87,7 +91,8 @@ this.app.use(BodyParser({ inflate: true, limit: "10mb" })); const app = this.app; - const api = Router({ mergeParams: true }); + //const api = Router({ mergeParams: true }); + const api = Router(); // eslint-disable-next-line @typescript-eslint/ban-ts-comment // @ts-ignore this.app = api; @@ -98,17 +103,22 @@ this.routes = (await registerRoutes(this, path.join(__dirname, "routes", "/"))).filter((r) => !!r); + api.use((req, res, next) => { + console.log(`[Server API Router] Incoming request: ${req.method} ${req.url}`); + next(); + }); + // 404 is not an error in express, so this should not be an error middleware // this is a fine place to put the 404 handler because its after we register the routes // and since its not an error middleware, our error handler below still works. // Emma [it/its] @ Rory& - the _ is required now, as pillarjs throw an error if you don't pass a param name now - api.use("*_", (req: Request, res: Response) => { - res.status(404).json({ - message: "Endpoint not found", - code: 404, - request: `${req.method} ${req.url}`, - }); - }); + // api.use("*_", (req: Request, res: Response) => { + // res.status(404).json({ + // message: "Endpoint not found", + // code: 404, + // request: `${req.method} ${req.url}`, + // }); + // }); this.app = app; @@ -120,14 +130,14 @@ app.use("/api/v8", api); app.use("/api/v9", api); app.use("/api/v10", api); // https://discord.com/developers/docs/change-log#api-v10 - app.use("/api", api); // allow unversioned requests + // app.use("/api", api); // allow unversioned requests app.use("/imageproxy/:hash/:size/:url", ImageProxy); - app.get("/", (req, res) => { - res.set("Cache-Control", "public, max-age=21600"); - return res.sendFile(path.join(PUBLIC_ASSETS_FOLDER, "index.html")); - }); + // app.get("/", (req, res) => { + // res.set("Cache-Control", "public, max-age=21600"); + // return res.sendFile(path.join(PUBLIC_ASSETS_FOLDER, "index.html")); + // }); app.get("/verify-email", (req, res) => { res.set("Cache-Control", "public, max-age=21600"); @@ -154,6 +164,13 @@ }); }); + let html = fs.readFileSync(path.join(ASSET_FOLDER_PATH, "client_test", "index.html"), { encoding: "utf-8" }); + console.log("call 3"); + + html = applyEnv(html); // update window.GLOBAL_ENV according to config + + html = applyPlugins(html); // inject our plugins + // current well-known location app.get("/.well-known/spacebar", (req, res) => { res.json({ @@ -202,6 +219,72 @@ if (logRequests) console.log(red(`Warning: Request logging is enabled! This will spam your console!\nTo disable this, unset the 'LOG_REQUESTS' environment variable!`)); + app.use("/assets", express.static(path.join(ASSET_FOLDER_PATH, "public"))); + app.use("/assets", express.static(path.join(ASSET_FOLDER_PATH, "cache"))); + + app.use("/assets/plugins", express.static(path.join(ASSET_FOLDER_PATH, "plugins"))); + app.use("/assets/inline-plugins", express.static(path.join(ASSET_FOLDER_PATH, "inline-plugins"))); + + const assetCache = new Map(); + + // Fetches uncached ( on disk ) assets from discord.com and stores them in memory cache. + app.get("/assets/:file", async (req, res) => { + delete req.headers.host; + + if (req.params.file.endsWith(".map")) return res.status(404); + + let response: FetchResponse; + let buffer: Buffer; + const cache = assetCache.get(req.params.file); + if (!cache) { + response = await fetch(`https://discord.com/assets/${req.params.file}`, { + headers: { ...(req.headers as { [key: string]: string }) }, + }); + buffer = await response.buffer(); + } else { + response = cache.response; + buffer = cache.buffer; + } + + [ + "content-length", + "content-security-policy", + "strict-transport-security", + "set-cookie", + "transfer-encoding", + "expect-ct", + "access-control-allow-origin", + "content-encoding", + ].forEach((headerName) => { + response.headers.delete(headerName); + }); + response.headers.forEach((value, name) => res.set(name, value)); + + assetCache.set(req.params.file, { buffer, response }); + + // TODO: I don't like this. Figure out a way to get client cacher to download *all* assets. + if (response.status == 200) { + console.warn(`[TestClient] Cache miss for file ${req.params.file}! Use 'npm run generate:client' to cache and patch.`); + await fs.promises.appendFile(path.join(ASSET_FOLDER_PATH, "cacheMisses"), req.params.file + "\n"); + } + + return res.send(buffer); + }); + + app.use((req, res, next) => { + console.log(`[TestClient Wildcard] Intercepted path: ${req.url}`); + + if (req.url.startsWith("/api") || req.url.startsWith("/__development")) { + console.log(`[TestClient Wildcard] Bypassing route (matched API guard): ${req.url}`); + return next ? next() : res.sendStatus(404); + } + + console.log(`[TestClient Wildcard] Serving index.html for: ${req.url}`); + res.set("Cache-Control", "public, max-age=" + 60 * 60 * 24); + res.set("content-type", "text/html"); + + return res.send(html); + }); await ProcessLifecycle.Ready(); return super.start(); } diff --git a/src/api/middlewares/TestClient.ts b/src/api/middlewares/TestClient.ts new file mode 100644 index 0000000..3d5e44b --- /dev/null +++ b/src/api/middlewares/TestClient.ts @@ -0,0 +1,144 @@ +import express, { Application } from "express"; +import fs from "node:fs"; +import path from "node:path"; +import fetch, { Response as FetchResponse, Headers } from "node-fetch"; +import { Config } from "@spacebar/util"; + +const ASSET_FOLDER_PATH = path.join(__dirname, "..", "..", "..", "assets"); + +export default function TestClient(app: Application) { + console.log("call"); + app.use("/assets", express.static(path.join(ASSET_FOLDER_PATH, "public"))); + app.use("/assets", express.static(path.join(ASSET_FOLDER_PATH, "cache"))); + console.log("call 2"); + + let html = fs.readFileSync(path.join(ASSET_FOLDER_PATH, "client_test", "index.html"), { encoding: "utf-8" }); + console.log("call 3"); + + html = applyEnv(html); // update window.GLOBAL_ENV according to config + + html = applyPlugins(html); // inject our plugins + app.use("/assets/plugins", express.static(path.join(ASSET_FOLDER_PATH, "plugins"))); + app.use("/assets/inline-plugins", express.static(path.join(ASSET_FOLDER_PATH, "inline-plugins"))); + + console.log("call 4"); + + // Asset memory cache + const assetCache = new Map(); + + // Fetches uncached ( on disk ) assets from discord.com and stores them in memory cache. + app.get("/assets/:file", async (req, res) => { + delete req.headers.host; + + if (req.params.file.endsWith(".map")) return res.status(404); + + let response: FetchResponse; + let buffer: Buffer; + const cache = assetCache.get(req.params.file); + if (!cache) { + response = await fetch(`https://discord.com/assets/${req.params.file}`, { + headers: { ...(req.headers as { [key: string]: string }) }, + }); + buffer = await response.buffer(); + } else { + response = cache.response; + buffer = cache.buffer; + } + + [ + "content-length", + "content-security-policy", + "strict-transport-security", + "set-cookie", + "transfer-encoding", + "expect-ct", + "access-control-allow-origin", + "content-encoding", + ].forEach((headerName) => { + response.headers.delete(headerName); + }); + response.headers.forEach((value, name) => res.set(name, value)); + + assetCache.set(req.params.file, { buffer, response }); + + // TODO: I don't like this. Figure out a way to get client cacher to download *all* assets. + if (response.status == 200) { + console.warn(`[TestClient] Cache miss for file ${req.params.file}! Use 'npm run generate:client' to cache and patch.`); + await fs.promises.appendFile(path.join(ASSET_FOLDER_PATH, "cacheMisses"), req.params.file + "\n"); + } + + return res.send(buffer); + }); + + console.log("call 5"); + + // Instead of our generated html, send developers.html for developers endpoint + app.get("/developers*", (req, res) => { + res.set("Cache-Control", "public, max-age=" + 60 * 60 * 24); // 24 hours + res.set("content-type", "text/html"); + res.send(fs.readFileSync(path.join(ASSET_FOLDER_PATH, "client_test", "developers.html"), { encoding: "utf-8" })); + }); + + console.log("call 6"); + + // Send our generated index.html for all routes. + app.get("*", (req, res, next) => { + console.log(`[TestClient Wildcard] Intercepted path: ${req.url}`); + + if (req.url.startsWith("/api") || req.url.startsWith("/__development")) { + console.log(`[TestClient Wildcard] Bypassing route (matched API guard): ${req.url}`); + return next ? next() : res.sendStatus(404); + } + + console.log(`[TestClient Wildcard] Serving index.html for: ${req.url}`); + res.set("Cache-Control", "public, max-age=" + 60 * 60 * 24); + res.set("content-type", "text/html"); + + return res.send(html); + }); + console.log("call 7"); +} + +// Apply gateway/cdn endpoint values from config to index.html. +export const applyEnv = (html: string): string => { + const config = Config.get(); + + const cdn = (config.cdn.endpointClient || config.cdn.endpointPublic || process.env.CDN || "").replace(/(https?)?(:\/\/?)/g, ""); + + const gateway = config.gateway.endpointClient || config.gateway.endpointPublic || process.env.GATEWAY || ""; + + if (cdn) html = html.replace(/CDN_HOST: .+/, `CDN_HOST: \`${cdn}\`,`); + + if (gateway) html = html.replace(/GATEWAY_ENDPOINT: .+/, `GATEWAY_ENDPOINT: \`${gateway}\`,`); + + return html; +}; + +// Injects inline, preload, and standard plugins into index.html. +export const applyPlugins = (html: string): string => { + // Inline plugins. Injected as `) + .join("\n"); + html = html.replace("", inline); + + // Preload plugins. Text content of each plugin is injected into head. + const preloadFiles = fs.readdirSync(path.join(ASSET_FOLDER_PATH, "preload-plugins")); + const preload = preloadFiles + .filter((x) => x.endsWith(".js")) + .map((x) => ``) + .join("\n"); + html = html.replace("", preload); + + // Normal plugins. Injected as `) + .join("\n"); + html = html.replace("", plugins); + + return html; +}; diff --git a/src/util/config/types/ClientConfiguration.ts b/src/util/config/types/ClientConfiguration.ts new file mode 100644 index 0000000..6434f15 --- /dev/null +++ b/src/util/config/types/ClientConfiguration.ts @@ -0,0 +1,24 @@ +/* + Fosscord: A FOSS re-implementation and extension of the Discord.com backend. + Copyright (C) 2023 Fosscord and Fosscord Contributors + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU Affero General Public License as published + by the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU Affero General Public License for more details. + + You should have received a copy of the GNU Affero General Public License + along with this program. If not, see . +*/ + +import { ClientReleaseConfiguration } from "."; + +export class ClientConfiguration { + releases: ClientReleaseConfiguration = new ClientReleaseConfiguration(); + useTestClient: boolean = true; +} diff --git a/src/util/config/types/EndpointConfiguration.ts b/src/util/config/types/EndpointConfiguration.ts index b1bccd2..c9f69e9 100644 --- a/src/util/config/types/EndpointConfiguration.ts +++ b/src/util/config/types/EndpointConfiguration.ts @@ -17,6 +17,7 @@ */ export class EndpointConfiguration { + endpointClient: string | null = null; endpointPrivate: string | null = null; endpointPublic: string | null = null; } diff --git a/src/util/config/types/subconfigurations/client/ClientReleaseConfiguration.ts b/src/util/config/types/subconfigurations/client/ClientReleaseConfiguration.ts new file mode 100644 index 0000000..1765167 --- /dev/null +++ b/src/util/config/types/subconfigurations/client/ClientReleaseConfiguration.ts @@ -0,0 +1,22 @@ +/* + Fosscord: A FOSS re-implementation and extension of the Discord.com backend. + Copyright (C) 2023 Fosscord and Fosscord Contributors + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU Affero General Public License as published + by the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU Affero General Public License for more details. + + You should have received a copy of the GNU Affero General Public License + along with this program. If not, see . +*/ + +export class ClientReleaseConfiguration { + useLocalRelease: boolean = true; //TODO + upstreamVersion: string = "0.0.264"; +} diff --git a/src/util/config/types/subconfigurations/client/index.ts b/src/util/config/types/subconfigurations/client/index.ts new file mode 100644 index 0000000..96bbb0c --- /dev/null +++ b/src/util/config/types/subconfigurations/client/index.ts @@ -0,0 +1 @@ +export * from "./ClientReleaseConfiguration"; diff --git a/src/util/config/types/subconfigurations/index.ts b/src/util/config/types/subconfigurations/index.ts index 82385df..f74a811 100644 --- a/src/util/config/types/subconfigurations/index.ts +++ b/src/util/config/types/subconfigurations/index.ts @@ -22,3 +22,4 @@ export * from "./limits"; export * from "./register"; export * from "./security"; +export * from "./client";