feat: consistently format all HTML, XML, JSON, CSS, JS, TS, SQL, TOML, YAML, and Markdown files as far as possible (#4193)

* feat: consistently format all HTML, XML, JSON, CSS, JS, TS, SQL, TOML, YAML, and Markdown files

* chore: deal with VS Code not being able to parse valid editorconfig syntax

Sometimes I'm surprised that computers even work.

* chore: get rid of IntelliJ IDE config files that should not be there

These were already added to the `.gitignore` a long time ago, and now
are being ignored by Prettier.

* fix: rename `tooling-config` `format` script to `fix` for it to run with Turbo
This commit is contained in:
Alejandro González
2025-08-16 19:40:31 +02:00
committed by GitHub
parent 6f59f4c110
commit 1454e3351e
130 changed files with 7959 additions and 7618 deletions

View File

@@ -1,3 +1,4 @@
**/dist
*.gltf
src/locales/
src/assets/**/*.svg

View File

@@ -0,0 +1 @@
**/*.rs

View File

@@ -1,10 +1,12 @@
{
"name": "@modrinth/app-playground",
"scripts": {
"build": "cargo build --release",
"lint": "cargo fmt --check && cargo clippy --all-targets",
"fix": "cargo clippy --all-targets --fix --allow-dirty && cargo fmt",
"dev": "cargo run",
"test": "cargo nextest run --all-targets --no-fail-fast"
}
"name": "@modrinth/app-playground",
"scripts": {
"build": "cargo build --release",
"lint": "cargo fmt --check && cargo clippy --all-targets",
"lint:ancillary": "prettier --check .",
"fix": "cargo clippy --all-targets --fix --allow-dirty && cargo fmt",
"fix:ancillary": "prettier --check .",
"dev": "cargo run",
"test": "cargo nextest run --all-targets --no-fail-fast"
}
}

2
apps/app/.prettierignore Normal file
View File

@@ -0,0 +1,2 @@
**/*.rs
src/api/oauth_utils/auth_code_reply/page.html

View File

@@ -1,6 +1,6 @@
[package]
name = "theseus_gui"
version = "1.0.0-local" # The actual version is set by the theseus-build workflow on tagging
version = "1.0.0-local" # The actual version is set by the theseus-build workflow on tagging
description = "The Modrinth App is a desktop application for managing your Minecraft mods"
license = "GPL-3.0-only"
repository = "https://github.com/modrinth/code/apps/app/"

View File

@@ -1,42 +1,43 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN"
"http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>CFBundleURLTypes</key>
<array>
<dict>
<key>CFBundleURLName</key>
<string>ModrinthApp</string>
<key>CFBundleURLSchemes</key>
<array>
<string>modrinth</string>
<string>modrinthscheme</string>
</array>
</dict>
</array>
<key>NSCameraUsageDescription</key>
<string>A Minecraft mod wants to access your camera.</string>
<key>NSMicrophoneUsageDescription</key>
<string>A Minecraft mod wants to access your microphone.</string>
<key>NSAppTransportSecurity</key>
<dict>
<key>NSExceptionDomains</key>
<dict>
<key>asset.localhost</key>
<dict>
<key>NSExceptionAllowsInsecureHTTPLoads</key>
<true/>
<key>NSIncludesSubdomains</key>
<true/>
</dict>
<key>textures.minecraft.net</key>
<dict>
<key>NSExceptionAllowsInsecureHTTPLoads</key>
<true/>
<key>NSIncludesSubdomains</key>
<true/>
</dict>
</dict>
</dict>
</dict>
<dict>
<key>CFBundleURLTypes</key>
<array>
<dict>
<key>CFBundleURLName</key>
<string>ModrinthApp</string>
<key>CFBundleURLSchemes</key>
<array>
<string>modrinth</string>
<string>modrinthscheme</string>
</array>
</dict>
</array>
<key>NSCameraUsageDescription</key>
<string>A Minecraft mod wants to access your camera.</string>
<key>NSMicrophoneUsageDescription</key>
<string>A Minecraft mod wants to access your microphone.</string>
<key>NSAppTransportSecurity</key>
<dict>
<key>NSExceptionDomains</key>
<dict>
<key>asset.localhost</key>
<dict>
<key>NSExceptionAllowsInsecureHTTPLoads</key>
<true />
<key>NSIncludesSubdomains</key>
<true />
</dict>
<key>textures.minecraft.net</key>
<dict>
<key>NSExceptionAllowsInsecureHTTPLoads</key>
<true />
<key>NSIncludesSubdomains</key>
<true />
</dict>
</dict>
</dict>
</dict>
</plist>

View File

@@ -1,10 +1,10 @@
{
"identifier": "ads",
"description": "",
"local": false,
"remote": {
"urls": ["https://modrinth.com/*", "http://localhost:3000/*"]
},
"webviews": ["ads-window"],
"permissions": ["ads:default"]
"identifier": "ads",
"description": "",
"local": false,
"remote": {
"urls": ["https://modrinth.com/*", "http://localhost:3000/*"]
},
"webviews": ["ads-window"],
"permissions": ["ads:default"]
}

View File

@@ -1,28 +1,28 @@
{
"identifier": "core",
"description": "",
"local": true,
"windows": ["main"],
"permissions": [
"core:default",
"core:path:default",
"core:event:default",
"core:window:default",
"core:app:default",
"core:resources:default",
"core:menu:default",
"core:tray:default",
"core:window:allow-create",
"core:window:allow-maximize",
"core:window:allow-toggle-maximize",
"core:window:allow-unmaximize",
"core:window:allow-minimize",
"core:window:allow-unminimize",
"core:window:allow-show",
"core:window:allow-hide",
"core:window:allow-close",
"core:window:allow-set-decorations",
"core:window:allow-start-dragging",
"core:webview:allow-set-webview-zoom"
]
"identifier": "core",
"description": "",
"local": true,
"windows": ["main"],
"permissions": [
"core:default",
"core:path:default",
"core:event:default",
"core:window:default",
"core:app:default",
"core:resources:default",
"core:menu:default",
"core:tray:default",
"core:window:allow-create",
"core:window:allow-maximize",
"core:window:allow-toggle-maximize",
"core:window:allow-unmaximize",
"core:window:allow-minimize",
"core:window:allow-unminimize",
"core:window:allow-show",
"core:window:allow-hide",
"core:window:allow-close",
"core:window:allow-set-decorations",
"core:window:allow-start-dragging",
"core:webview:allow-set-webview-zoom"
]
}

View File

@@ -1,50 +1,47 @@
{
"identifier": "plugins",
"description": "",
"local": true,
"windows": ["main"],
"permissions": [
"dialog:allow-open",
"dialog:allow-confirm",
"opener:default",
"os:allow-platform",
"os:allow-version",
"os:allow-os-type",
"os:allow-family",
"os:allow-arch",
"os:allow-exe-extension",
"os:allow-locale",
"os:allow-hostname",
"deep-link:default",
"window-state:default",
"window-state:allow-restore-state",
"window-state:allow-save-window-state",
{
"identifier": "http:default",
"allow": [
{ "url": "https://modrinth.com/*" },
{ "url": "https://*.modrinth.com/*" }
]
},
"identifier": "plugins",
"description": "",
"local": true,
"windows": ["main"],
"permissions": [
"dialog:allow-open",
"dialog:allow-confirm",
"opener:default",
"os:allow-platform",
"os:allow-version",
"os:allow-os-type",
"os:allow-family",
"os:allow-arch",
"os:allow-exe-extension",
"os:allow-locale",
"os:allow-hostname",
"deep-link:default",
"window-state:default",
"window-state:allow-restore-state",
"window-state:allow-save-window-state",
"auth:default",
"import:default",
"jre:default",
"logs:default",
"metadata:default",
"minecraft-skins:default",
"mr-auth:default",
"profile-create:default",
"pack:default",
"process:default",
"profile:default",
"cache:default",
"settings:default",
"tags:default",
"utils:default",
"ads:default",
"friends:default",
"worlds:default"
]
{
"identifier": "http:default",
"allow": [{ "url": "https://modrinth.com/*" }, { "url": "https://*.modrinth.com/*" }]
},
"auth:default",
"import:default",
"jre:default",
"logs:default",
"metadata:default",
"minecraft-skins:default",
"mr-auth:default",
"profile-create:default",
"pack:default",
"process:default",
"profile:default",
"cache:default",
"settings:default",
"tags:default",
"utils:default",
"ads:default",
"friends:default",
"worlds:default"
]
}

View File

@@ -1,7 +1,7 @@
{
"identifier": "updater",
"description": "",
"local": true,
"windows": ["main"],
"permissions": ["updater:default"]
"identifier": "updater",
"description": "",
"local": true,
"windows": ["main"],
"permissions": ["updater:default"]
}

View File

@@ -1,19 +1,21 @@
{
"name": "@modrinth/app",
"scripts": {
"tauri": "tauri",
"build": "tauri build",
"dev": "tauri dev",
"test": "cargo nextest run --all-targets --no-fail-fast",
"lint": "cargo fmt --check && cargo clippy --all-targets",
"fix": "cargo clippy --all-targets --fix --allow-dirty && cargo fmt"
},
"devDependencies": {
"@tauri-apps/cli": "2.5.0"
},
"dependencies": {
"@modrinth/app-frontend": "workspace:*",
"@modrinth/app-lib": "workspace:*",
"@modrinth/daedalus": "workspace:*"
}
"name": "@modrinth/app",
"scripts": {
"tauri": "tauri",
"build": "tauri build",
"dev": "tauri dev",
"test": "cargo nextest run --all-targets --no-fail-fast",
"lint": "cargo fmt --check && cargo clippy --all-targets",
"lint:ancillary": "prettier --check .",
"fix": "cargo clippy --all-targets --fix --allow-dirty && cargo fmt",
"fix:ancillary": "prettier --write ."
},
"devDependencies": {
"@tauri-apps/cli": "2.5.0"
},
"dependencies": {
"@modrinth/app-frontend": "workspace:*",
"@modrinth/app-lib": "workspace:*",
"@modrinth/daedalus": "workspace:*"
}
}

View File

@@ -1,106 +1,106 @@
document.addEventListener(
'click',
function (e) {
window.top.postMessage({ modrinthAdClick: true }, 'https://modrinth.com')
'click',
function (e) {
window.top.postMessage({ modrinthAdClick: true }, 'https://modrinth.com')
let target = e.target
while (target != null) {
if (target.matches('a')) {
e.preventDefault()
if (target.href) {
window.top.postMessage({ modrinthOpenUrl: target.href }, 'https://modrinth.com')
}
break
}
target = target.parentElement
}
},
true,
let target = e.target
while (target != null) {
if (target.matches('a')) {
e.preventDefault()
if (target.href) {
window.top.postMessage({ modrinthOpenUrl: target.href }, 'https://modrinth.com')
}
break
}
target = target.parentElement
}
},
true,
)
window.open = (url, target, features) => {
window.top.postMessage({ modrinthOpenUrl: url }, 'https://modrinth.com')
window.top.postMessage({ modrinthOpenUrl: url }, 'https://modrinth.com')
}
function muteAudioContext() {
if (window.AudioContext || window.webkitAudioContext) {
const AudioContext = window.AudioContext || window.webkitAudioContext
const originalCreateMediaElementSource = AudioContext.prototype.createMediaElementSource
const originalCreateMediaStreamSource = AudioContext.prototype.createMediaStreamSource
const originalCreateMediaStreamTrackSource = AudioContext.prototype.createMediaStreamTrackSource
const originalCreateBufferSource = AudioContext.prototype.createBufferSource
const originalCreateOscillator = AudioContext.prototype.createOscillator
if (window.AudioContext || window.webkitAudioContext) {
const AudioContext = window.AudioContext || window.webkitAudioContext
const originalCreateMediaElementSource = AudioContext.prototype.createMediaElementSource
const originalCreateMediaStreamSource = AudioContext.prototype.createMediaStreamSource
const originalCreateMediaStreamTrackSource = AudioContext.prototype.createMediaStreamTrackSource
const originalCreateBufferSource = AudioContext.prototype.createBufferSource
const originalCreateOscillator = AudioContext.prototype.createOscillator
AudioContext.prototype.createGain = function () {
const gain = originalCreateGain.call(this)
gain.gain.value = 0
return gain
}
AudioContext.prototype.createGain = function () {
const gain = originalCreateGain.call(this)
gain.gain.value = 0
return gain
}
AudioContext.prototype.createMediaElementSource = function (mediaElement) {
const source = originalCreateMediaElementSource.call(this, mediaElement)
source.connect(this.createGain())
return source
}
AudioContext.prototype.createMediaElementSource = function (mediaElement) {
const source = originalCreateMediaElementSource.call(this, mediaElement)
source.connect(this.createGain())
return source
}
AudioContext.prototype.createMediaStreamSource = function (mediaStream) {
const source = originalCreateMediaStreamSource.call(this, mediaStream)
source.connect(this.createGain())
return source
}
AudioContext.prototype.createMediaStreamSource = function (mediaStream) {
const source = originalCreateMediaStreamSource.call(this, mediaStream)
source.connect(this.createGain())
return source
}
AudioContext.prototype.createMediaStreamTrackSource = function (mediaStreamTrack) {
const source = originalCreateMediaStreamTrackSource.call(this, mediaStreamTrack)
source.connect(this.createGain())
return source
}
AudioContext.prototype.createMediaStreamTrackSource = function (mediaStreamTrack) {
const source = originalCreateMediaStreamTrackSource.call(this, mediaStreamTrack)
source.connect(this.createGain())
return source
}
AudioContext.prototype.createBufferSource = function () {
const source = originalCreateBufferSource.call(this)
source.connect(this.createGain())
return source
}
AudioContext.prototype.createBufferSource = function () {
const source = originalCreateBufferSource.call(this)
source.connect(this.createGain())
return source
}
AudioContext.prototype.createOscillator = function () {
const oscillator = originalCreateOscillator.call(this)
oscillator.connect(this.createGain())
return oscillator
}
}
AudioContext.prototype.createOscillator = function () {
const oscillator = originalCreateOscillator.call(this)
oscillator.connect(this.createGain())
return oscillator
}
}
}
function muteVideo(mediaElement) {
let count = Number(mediaElement.getAttribute('data-modrinth-muted-count') ?? 0)
let count = Number(mediaElement.getAttribute('data-modrinth-muted-count') ?? 0)
if (!mediaElement.muted || mediaElement.volume !== 0) {
mediaElement.muted = true
mediaElement.volume = 0
if (!mediaElement.muted || mediaElement.volume !== 0) {
mediaElement.muted = true
mediaElement.volume = 0
mediaElement.setAttribute('data-modrinth-muted-count', count + 1)
}
mediaElement.setAttribute('data-modrinth-muted-count', count + 1)
}
if (count > 5) {
// Video is detected as malicious, so it is removed from the page
mediaElement.remove()
}
if (count > 5) {
// Video is detected as malicious, so it is removed from the page
mediaElement.remove()
}
}
function muteVideos() {
document.querySelectorAll('video, audio').forEach(function (mediaElement) {
muteVideo(mediaElement)
document.querySelectorAll('video, audio').forEach(function (mediaElement) {
muteVideo(mediaElement)
if (!mediaElement.hasAttribute('data-modrinth-muted')) {
mediaElement.addEventListener('volumechange', () => muteVideo(mediaElement))
if (!mediaElement.hasAttribute('data-modrinth-muted')) {
mediaElement.addEventListener('volumechange', () => muteVideo(mediaElement))
mediaElement.setAttribute('data-modrinth-muted', 'true')
}
})
mediaElement.setAttribute('data-modrinth-muted', 'true')
}
})
}
document.addEventListener('DOMContentLoaded', () => {
muteVideos()
muteAudioContext()
muteVideos()
muteAudioContext()
const observer = new MutationObserver(muteVideos)
observer.observe(document.body, { childList: true, subtree: true })
const observer = new MutationObserver(muteVideos)
observer.observe(document.body, { childList: true, subtree: true })
})

View File

@@ -1,37 +1,37 @@
{
"bundle": {
"createUpdaterArtifacts": "v1Compatible",
"windows": {
"signCommand": {
"cmd": "jsign",
"args": [
"sign",
"--verbose",
"--storetype",
"DIGICERTONE",
"--keystore",
"https://clientauth.one.digicert.com",
"--storepass",
"env:DIGICERT_ONE_SIGNER_CREDENTIALS",
"--tsaurl",
"https://timestamp.sectigo.com,http://timestamp.digicert.com",
"%1"
]
}
}
},
"build": {
"features": ["updater"]
},
"app": {
"security": {
"capabilities": ["ads", "core", "plugins", "updater"]
}
},
"plugins": {
"updater": {
"pubkey": "dW50cnVzdGVkIGNvbW1lbnQ6IG1pbmlzaWduIHB1YmxpYyBrZXk6IDIwMzM5QkE0M0FCOERBMzkKUldRNTJyZzZwSnN6SUdPRGdZREtUUGxMblZqeG9OVHYxRUlRTzJBc2U3MUNJaDMvZDQ1UytZZmYK",
"endpoints": ["https://launcher-files.modrinth.com/updates.json"]
}
}
"bundle": {
"createUpdaterArtifacts": "v1Compatible",
"windows": {
"signCommand": {
"cmd": "jsign",
"args": [
"sign",
"--verbose",
"--storetype",
"DIGICERTONE",
"--keystore",
"https://clientauth.one.digicert.com",
"--storepass",
"env:DIGICERT_ONE_SIGNER_CREDENTIALS",
"--tsaurl",
"https://timestamp.sectigo.com,http://timestamp.digicert.com",
"%1"
]
}
}
},
"build": {
"features": ["updater"]
},
"app": {
"security": {
"capabilities": ["ads", "core", "plugins", "updater"]
}
},
"plugins": {
"updater": {
"pubkey": "dW50cnVzdGVkIGNvbW1lbnQ6IG1pbmlzaWduIHB1YmxpYyBrZXk6IDIwMzM5QkE0M0FCOERBMzkKUldRNTJyZzZwSnN6SUdPRGdZREtUUGxMblZqeG9OVHYxRUlRTzJBc2U3MUNJaDMvZDQ1UytZZmYK",
"endpoints": ["https://launcher-files.modrinth.com/updates.json"]
}
}
}

View File

@@ -1,100 +1,100 @@
{
"$schema": "https://schema.tauri.app/config/2",
"build": {
"beforeDevCommand": "pnpm turbo run dev --filter=@modrinth/app-frontend",
"beforeBuildCommand": "pnpm turbo run build --filter=@modrinth/app-frontend",
"frontendDist": "../app-frontend/dist",
"devUrl": "http://localhost:1420"
},
"bundle": {
"active": true,
"category": "Game",
"copyright": "",
"targets": "all",
"externalBin": [],
"icon": ["icons/128x128.png", "icons/128x128@2x.png", "icons/icon.icns", "icons/icon.ico"],
"windows": {
"nsis": {
"installMode": "currentUser",
"installerHooks": "./nsis/hooks.nsi"
}
},
"longDescription": "",
"macOS": {
"entitlements": "App.entitlements",
"exceptionDomain": "",
"frameworks": [],
"providerShortName": null,
"signingIdentity": null
},
"shortDescription": "",
"linux": {
"deb": {
"depends": []
}
},
"fileAssociations": [
{
"ext": ["mrpack"],
"mimeType": "application/x-modrinth-modpack+zip"
}
]
},
"productName": "Modrinth App",
"version": "../app-frontend/package.json",
"mainBinaryName": "Modrinth App",
"identifier": "ModrinthApp",
"plugins": {
"deep-link": {
"desktop": {
"schemes": ["modrinth"]
},
"mobile": []
}
},
"app": {
"withGlobalTauri": false,
"macOSPrivateApi": true,
"windows": [
{
"titleBarStyle": "Overlay",
"hiddenTitle": true,
"fullscreen": false,
"height": 800,
"resizable": true,
"title": "Modrinth App",
"label": "main",
"width": 1280,
"minHeight": 700,
"minWidth": 1100,
"visible": true,
"zoomHotkeysEnabled": false,
"decorations": false
}
],
"security": {
"assetProtocol": {
"scope": [
"$APPDATA/caches/icons/*",
"$APPCONFIG/caches/icons/*",
"$CONFIG/caches/icons/*",
"$APPDATA/profiles/*/saves/*/icon.png",
"$APPCONFIG/profiles/*/saves/*/icon.png",
"$CONFIG/profiles/*/saves/*/icon.png"
],
"enable": true
},
"capabilities": ["ads", "core", "plugins"],
"csp": {
"default-src": "'self' customprotocol: asset:",
"connect-src": "ipc: http://ipc.localhost https://modrinth.com https://*.modrinth.com https://*.posthog.com https://*.sentry.io https://api.mclo.gs 'self' data: blob:",
"font-src": ["https://cdn-raw.modrinth.com/fonts/"],
"img-src": "https: 'unsafe-inline' 'self' asset: http://asset.localhost http://textures.minecraft.net blob: data:",
"style-src": "'unsafe-inline' 'self'",
"script-src": "https://*.posthog.com https://tally.so/widgets/embed.js 'self'",
"frame-src": "https://www.youtube.com https://www.youtube-nocookie.com https://discord.com https://tally.so/popup/ 'self'",
"media-src": "https://*.githubusercontent.com"
}
}
}
"$schema": "https://schema.tauri.app/config/2",
"build": {
"beforeDevCommand": "pnpm turbo run dev --filter=@modrinth/app-frontend",
"beforeBuildCommand": "pnpm turbo run build --filter=@modrinth/app-frontend",
"frontendDist": "../app-frontend/dist",
"devUrl": "http://localhost:1420"
},
"bundle": {
"active": true,
"category": "Game",
"copyright": "",
"targets": "all",
"externalBin": [],
"icon": ["icons/128x128.png", "icons/128x128@2x.png", "icons/icon.icns", "icons/icon.ico"],
"windows": {
"nsis": {
"installMode": "currentUser",
"installerHooks": "./nsis/hooks.nsi"
}
},
"longDescription": "",
"macOS": {
"entitlements": "App.entitlements",
"exceptionDomain": "",
"frameworks": [],
"providerShortName": null,
"signingIdentity": null
},
"shortDescription": "",
"linux": {
"deb": {
"depends": []
}
},
"fileAssociations": [
{
"ext": ["mrpack"],
"mimeType": "application/x-modrinth-modpack+zip"
}
]
},
"productName": "Modrinth App",
"version": "../app-frontend/package.json",
"mainBinaryName": "Modrinth App",
"identifier": "ModrinthApp",
"plugins": {
"deep-link": {
"desktop": {
"schemes": ["modrinth"]
},
"mobile": []
}
},
"app": {
"withGlobalTauri": false,
"macOSPrivateApi": true,
"windows": [
{
"titleBarStyle": "Overlay",
"hiddenTitle": true,
"fullscreen": false,
"height": 800,
"resizable": true,
"title": "Modrinth App",
"label": "main",
"width": 1280,
"minHeight": 700,
"minWidth": 1100,
"visible": true,
"zoomHotkeysEnabled": false,
"decorations": false
}
],
"security": {
"assetProtocol": {
"scope": [
"$APPDATA/caches/icons/*",
"$APPCONFIG/caches/icons/*",
"$CONFIG/caches/icons/*",
"$APPDATA/profiles/*/saves/*/icon.png",
"$APPCONFIG/profiles/*/saves/*/icon.png",
"$CONFIG/profiles/*/saves/*/icon.png"
],
"enable": true
},
"capabilities": ["ads", "core", "plugins"],
"csp": {
"default-src": "'self' customprotocol: asset:",
"connect-src": "ipc: http://ipc.localhost https://modrinth.com https://*.modrinth.com https://*.posthog.com https://*.sentry.io https://api.mclo.gs 'self' data: blob:",
"font-src": ["https://cdn-raw.modrinth.com/fonts/"],
"img-src": "https: 'unsafe-inline' 'self' asset: http://asset.localhost http://textures.minecraft.net blob: data:",
"style-src": "'unsafe-inline' 'self'",
"script-src": "https://*.posthog.com https://tally.so/widgets/embed.js 'self'",
"frame-src": "https://www.youtube.com https://www.youtube-nocookie.com https://discord.com https://tally.so/popup/ 'self'",
"media-src": "https://*.githubusercontent.com"
}
}
}
}

View File

@@ -1,3 +1,3 @@
{
"mainBinaryName": "ModrinthApp"
"mainBinaryName": "ModrinthApp"
}

View File

@@ -1,24 +1,24 @@
{
"app": {
"windows": [
{
"titleBarStyle": "Overlay",
"hiddenTitle": true,
"fullscreen": false,
"height": 800,
"resizable": true,
"title": "Modrinth App",
"width": 1280,
"minHeight": 700,
"minWidth": 1100,
"visible": false,
"zoomHotkeysEnabled": false,
"decorations": true,
"trafficLightPosition": {
"x": 15.0,
"y": 22.0
}
}
]
}
"app": {
"windows": [
{
"titleBarStyle": "Overlay",
"hiddenTitle": true,
"fullscreen": false,
"height": 800,
"resizable": true,
"title": "Modrinth App",
"width": 1280,
"minHeight": 700,
"minWidth": 1100,
"visible": false,
"zoomHotkeysEnabled": false,
"decorations": true,
"trafficLightPosition": {
"x": 15.0,
"y": 22.0
}
}
]
}
}

View File

@@ -1,14 +1,14 @@
{
"$schema": "../../node_modules/turbo/schema.json",
"extends": ["//"],
"tasks": {
// Running Clippy and tests on a Tauri application requires
// the frontend to be built at least once first
"lint": {
"dependsOn": ["@modrinth/app-frontend#build"]
},
"test": {
"dependsOn": ["@modrinth/app-frontend#build"]
}
}
"$schema": "../../node_modules/turbo/schema.json",
"extends": ["//"],
"tasks": {
// Running Clippy and tests on a Tauri application requires
// the frontend to be built at least once first
"lint": {
"dependsOn": ["@modrinth/app-frontend#build"]
},
"test": {
"dependsOn": ["@modrinth/app-frontend#build"]
}
}
}

View File

@@ -0,0 +1 @@
**/*.rs

View File

@@ -16,7 +16,14 @@ serde_json.workspace = true
serde-xml-rs.workspace = true
thiserror.workspace = true
reqwest = { workspace = true, features = ["stream", "json", "rustls-tls-native-roots"] }
async_zip = { workspace = true, features = ["chrono", "tokio-fs", "deflate", "bzip2", "zstd", "deflate64"] }
async_zip = { workspace = true, features = [
"chrono",
"tokio-fs",
"deflate",
"bzip2",
"zstd",
"deflate64",
] }
chrono = { workspace = true, features = ["serde"] }
bytes.workspace = true
rust-s3.workspace = true

File diff suppressed because it is too large Load Diff

View File

@@ -1,13 +1,15 @@
{
"name": "@modrinth/daedalus_client",
"scripts": {
"build": "cargo build --release",
"lint": "cargo fmt --check && cargo clippy --all-targets",
"fix": "cargo clippy --all-targets --fix --allow-dirty && cargo fmt",
"dev": "cargo run",
"test": "cargo nextest run --all-targets --no-fail-fast"
},
"dependencies": {
"@modrinth/daedalus": "workspace:*"
}
"name": "@modrinth/daedalus_client",
"scripts": {
"build": "cargo build --release",
"lint": "cargo fmt --check && cargo clippy --all-targets",
"lint:ancillary": "prettier --check .",
"fix": "cargo clippy --all-targets --fix --allow-dirty && cargo fmt",
"fix:ancillary": "prettier --write .",
"dev": "cargo run",
"test": "cargo nextest run --all-targets --no-fail-fast"
},
"dependencies": {
"@modrinth/daedalus": "workspace:*"
}
}

View File

@@ -0,0 +1 @@
**/*.svg

View File

@@ -1,4 +1,4 @@
{
"recommendations": ["astro-build.astro-vscode"],
"unwantedRecommendations": []
"recommendations": ["astro-build.astro-vscode"],
"unwantedRecommendations": []
}

View File

@@ -1,11 +1,11 @@
{
"version": "0.2.0",
"configurations": [
{
"command": "./node_modules/.bin/astro dev",
"name": "Development server",
"request": "launch",
"type": "node-terminal"
}
]
"version": "0.2.0",
"configurations": [
{
"command": "./node_modules/.bin/astro dev",
"name": "Development server",
"request": "launch",
"type": "node-terminal"
}
]
}

View File

@@ -4,53 +4,53 @@ import starlightOpenAPI, { openAPISidebarGroups } from 'starlight-openapi'
// https://astro.build/config
export default defineConfig({
site: 'https://docs.modrinth.com',
integrations: [
starlight({
title: 'Modrinth Documentation',
favicon: '/favicon.ico',
editLink: {
baseUrl: 'https://github.com/modrinth/code/edit/main/apps/docs/',
},
social: {
github: 'https://github.com/modrinth/code',
discord: 'https://discord.modrinth.com',
'x.com': 'https://x.com/modrinth',
mastodon: 'https://floss.social/@modrinth',
threads: 'https://threads.net/@modrinth',
},
logo: {
light: './src/assets/light-logo.svg',
dark: './src/assets/dark-logo.svg',
replacesTitle: true,
},
customCss: [
'@modrinth/assets/styles/variables.scss',
'@modrinth/assets/styles/inter.scss',
'./src/styles/modrinth.css',
],
plugins: [
// Generate the OpenAPI documentation pages.
starlightOpenAPI([
{
base: 'api',
label: 'Modrinth API',
schema: './public/openapi.yaml',
},
]),
],
sidebar: [
{
label: 'Contributing to Modrinth',
autogenerate: { directory: 'contributing' },
},
{
label: 'Guides',
autogenerate: { directory: 'guide' },
},
// Add the generated sidebar group to the sidebar.
...openAPISidebarGroups,
],
}),
],
site: 'https://docs.modrinth.com',
integrations: [
starlight({
title: 'Modrinth Documentation',
favicon: '/favicon.ico',
editLink: {
baseUrl: 'https://github.com/modrinth/code/edit/main/apps/docs/',
},
social: {
github: 'https://github.com/modrinth/code',
discord: 'https://discord.modrinth.com',
'x.com': 'https://x.com/modrinth',
mastodon: 'https://floss.social/@modrinth',
threads: 'https://threads.net/@modrinth',
},
logo: {
light: './src/assets/light-logo.svg',
dark: './src/assets/dark-logo.svg',
replacesTitle: true,
},
customCss: [
'@modrinth/assets/styles/variables.scss',
'@modrinth/assets/styles/inter.scss',
'./src/styles/modrinth.css',
],
plugins: [
// Generate the OpenAPI documentation pages.
starlightOpenAPI([
{
base: 'api',
label: 'Modrinth API',
schema: './public/openapi.yaml',
},
]),
],
sidebar: [
{
label: 'Contributing to Modrinth',
autogenerate: { directory: 'contributing' },
},
{
label: 'Guides',
autogenerate: { directory: 'guide' },
},
// Add the generated sidebar group to the sidebar.
...openAPISidebarGroups,
],
}),
],
})

View File

@@ -1,22 +1,24 @@
{
"name": "@modrinth/docs",
"type": "module",
"version": "0.0.1",
"scripts": {
"dev": "astro dev",
"start": "astro dev",
"lint": "astro check",
"build": "astro build",
"preview": "astro preview",
"astro": "astro"
},
"dependencies": {
"@astrojs/check": "^0.9.4",
"@astrojs/starlight": "^0.32.2",
"@modrinth/assets": "workspace:*",
"astro": "^5.4.1",
"sharp": "^0.33.5",
"starlight-openapi": "^0.14.0",
"typescript": "^5.8.2"
}
"name": "@modrinth/docs",
"type": "module",
"version": "0.0.1",
"scripts": {
"dev": "astro dev",
"start": "astro dev",
"lint": "astro check",
"lint:ancillary": "prettier --check .",
"fix:ancillary": "prettier --write .",
"build": "astro build",
"preview": "astro preview",
"astro": "astro"
},
"dependencies": {
"@astrojs/check": "^0.9.4",
"@astrojs/starlight": "^0.32.2",
"@modrinth/assets": "workspace:*",
"astro": "^5.4.1",
"sharp": "^0.33.5",
"starlight-openapi": "^0.14.0",
"typescript": "^5.8.2"
}
}

View File

@@ -1,7 +1,7 @@
import { defineCollection } from 'astro:content';
import { docsLoader } from '@astrojs/starlight/loaders';
import { docsSchema } from '@astrojs/starlight/schema';
import { defineCollection } from 'astro:content'
import { docsLoader } from '@astrojs/starlight/loaders'
import { docsSchema } from '@astrojs/starlight/schema'
export const collections = {
docs: defineCollection({ loader: docsLoader(), schema: docsSchema() }),
};
docs: defineCollection({ loader: docsLoader(), schema: docsSchema() }),
}

View File

@@ -8,7 +8,7 @@ Modrinth allows developers to create applications which, once authorized by a Mo
If you're familiar with OAuth 2, these are the URLs you will need:
| Name | URL |
|--------------------|--------------------------------------------------|
| ------------------ | ------------------------------------------------ |
| Authorization page | `https://modrinth.com/auth/authorize` |
| Token exchange | `https://api.modrinth.com/_internal/oauth/token` |
@@ -31,7 +31,7 @@ After you've registered your application, it is important that you take note of
Once the user is ready to authorize your application, you need to construct a URL to redirect them to. The authorization URL for Modrinth is `https://api.modrinth.com/_internal/oauth/token`. Supply the following query parameters:
| Query parameter | Description |
|-----------------|-------------------------------------------------------------------------------------------|
| --------------- | ----------------------------------------------------------------------------------------- |
| `response_type` | In Modrinth this always needs to be `code`, since only code grants are supported |
| `client_id` | The application identifier found in the settings |
| `scope` | The permissions you need access to |
@@ -45,7 +45,7 @@ The scope identifiers are currently best found in the backend source code locate
The redirect URI is the endpoint on your server that will receive the code which can eventually be used to act on the user's behalf. For security reasons the redirect URI used has to be allowlisted in your application settings. The redirect will contain the following query parameters:
| Query parameter | Description |
|-----------------|----------------------------------------------------|
| --------------- | -------------------------------------------------- |
| `code` | The code that can be exchanged for an access token |
| `client_id` | Your client id |
| `redirect_uri` | The redirect URI which was used |
@@ -58,7 +58,7 @@ If you've followed the previous section on getting authorization, you should now
In the body use these fields:
| Field | Description |
|----------------|--------------------------------------------------------------|
| -------------- | ------------------------------------------------------------ |
| `code` | The authorization code |
| `client_id` | Your client id, the same as in the authorization request |
| `redirect_uri` | The redirect URI which was redirected to after authorization |
@@ -67,7 +67,7 @@ In the body use these fields:
If the request succeeds, you should receive a JSON payload with these fields:
| Field | Description |
|----------------|------------------------------------------------------|
| -------------- | ---------------------------------------------------- |
| `access_token` | The access token you can use to access the API |
| `token_type` | Currently only `Bearer` |
| `expires_in` | The amount of seconds until the access token expires |
@@ -77,19 +77,11 @@ To use this access token, you attach it to API requests in the `Authorization` h
If you have any questions, you're welcome to ask in #api-development in the [Discord guild], or create a ticket on the [support portal].
[RFC 6749]: https://datatracker.ietf.org/doc/html/rfc6749
[register an application]: https://modrinth.com/settings/applications
[principle of least privilege]: https://en.wikipedia.org/wiki/Principle_of_least_privilege
[`apps/labrinth/src/models/v3/pats.rs`]: https://github.com/modrinth/code/blob/main/apps/labrinth/src/models/v3/pats.rs
[CSRF]: https://en.wikipedia.org/wiki/Cross-site_request_forgery
[Clickjacking]: https://en.wikipedia.org/wiki/Clickjacking
[`/user` endpoint]: https://docs.modrinth.com/api/operations/getuserfromauth/
[Discord guild]: https://discord.modrinth.com
[support portal]: https://support.modrinth.com/en/

View File

@@ -2,53 +2,53 @@
::backdrop,
:root[data-theme='light'],
[data-theme='light'] ::backdrop {
--sl-font-system: Inter, -apple-system, BlinkMacSystemFont, Segoe UI, Oxygen, Ubuntu, Roboto,
Cantarell, Fira Sans, Droid Sans, Helvetica Neue, sans-serif;
--sl-font-system: Inter, -apple-system, BlinkMacSystemFont, Segoe UI, Oxygen, Ubuntu, Roboto,
Cantarell, Fira Sans, Droid Sans, Helvetica Neue, sans-serif;
--sl-color-white: var(--color-contrast); /* “white” */
--sl-color-gray-1: var(--color-base);
--sl-color-gray-2: var(--color-base);
--sl-color-gray-3: var(--color-base);
--sl-color-gray-4: var(--color-raised-bg);
--sl-color-gray-5: var(--color-button-bg);
--sl-color-gray-6: var(--color-raised-bg);
--sl-color-black: var(--color-accent-contrast);
--sl-color-white: var(--color-contrast); /* “white” */
--sl-color-gray-1: var(--color-base);
--sl-color-gray-2: var(--color-base);
--sl-color-gray-3: var(--color-base);
--sl-color-gray-4: var(--color-raised-bg);
--sl-color-gray-5: var(--color-button-bg);
--sl-color-gray-6: var(--color-raised-bg);
--sl-color-black: var(--color-accent-contrast);
--sl-color-accent-low: var(--color-green-highlight);
--sl-color-accent: var(--color-brand);
--sl-color-accent-high: var(--color-brand-highlight);
--sl-color-accent-low: var(--color-green-highlight);
--sl-color-accent: var(--color-brand);
--sl-color-accent-high: var(--color-brand-highlight);
--sl-color-orange-low: var(--color-orange-highlight);
--sl-color-orange: var(--color-orange);
--sl-color-orange-high: var(--color-orange-highlight);
--sl-color-orange-low: var(--color-orange-highlight);
--sl-color-orange: var(--color-orange);
--sl-color-orange-high: var(--color-orange-highlight);
--sl-color-green-low: var(--color-green-highlight);
--sl-color-green: var(--color-green);
--sl-color-green-high: var(--color-green-highlight);
--sl-color-green-low: var(--color-green-highlight);
--sl-color-green: var(--color-green);
--sl-color-green-high: var(--color-green-highlight);
--sl-color-blue-low: var(--color-blue-highlight);
--sl-color-blue: var(--color-blue);
--sl-color-blue-high: var(--color-blue-highlight);
--sl-color-blue-low: var(--color-blue-highlight);
--sl-color-blue: var(--color-blue);
--sl-color-blue-high: var(--color-blue-highlight);
--sl-color-purple-low: var(--color-purple-highlight);
--sl-color-purple: var(--color-purple);
--sl-color-purple-high: var(--color-purple-highlight);
--sl-color-purple-low: var(--color-purple-highlight);
--sl-color-purple: var(--color-purple);
--sl-color-purple-high: var(--color-purple-highlight);
--sl-color-red-low: var(--color-red-highlight);
--sl-color-red: var(--color-red);
--sl-color-red-high: var(--color-red-highlight);
--sl-color-red-low: var(--color-red-highlight);
--sl-color-red: var(--color-red);
--sl-color-red-high: var(--color-red-highlight);
--sl-color-text: var(--color-base);
--sl-color-text-accent: var(--color-brand);
--sl-color-text-invert: var(--color-accent-contrast);
--sl-color-bg: var(--color-bg);
--sl-color-bg-nav: var(--color-raised-bg);
--sl-color-bg-sidebar: var(--color-raised-bg);
--sl-color-bg-inline-code: var(--color-button-bg);
--sl-color-bg-accent: var(--color-brand-highlight);
--sl-color-text: var(--color-base);
--sl-color-text-accent: var(--color-brand);
--sl-color-text-invert: var(--color-accent-contrast);
--sl-color-bg: var(--color-bg);
--sl-color-bg-nav: var(--color-raised-bg);
--sl-color-bg-sidebar: var(--color-raised-bg);
--sl-color-bg-inline-code: var(--color-button-bg);
--sl-color-bg-accent: var(--color-brand-highlight);
}
:root[data-theme='light'],
[data-theme='light'] ::backdrop {
--sl-color-bg: var(--color-raised-bg);
--sl-color-bg: var(--color-raised-bg);
}

View File

@@ -1,3 +1,3 @@
{
"extends": "astro/tsconfigs/strict"
"extends": "astro/tsconfigs/strict"
}

View File

@@ -3,3 +3,5 @@
**/.output
src/generated/**
src/locales/**
src/public/news/feed
src/assets/**/*.svg

View File

@@ -72,5 +72,5 @@
"xss": "^1.0.14"
},
"web-types": "../../web-types.json",
"prettier": "@modrinth/tooling-config/prettier.nuxt.config.js"
"prettier": "@modrinth/tooling-config/frontend.prettier.config.cjs"
}

View File

@@ -1,186 +1,186 @@
{
"articles": [
{
"title": "Skins — Now in Modrinth App!",
"summary": "Customize your look, save your favorite skins, and swap them out in a flash, all within Modrinth App.",
"thumbnail": "https://modrinth.com/news/article/skins-now-in-modrinth-app/thumbnail.webp",
"date": "2025-07-06T23:45:00.000Z",
"link": "https://modrinth.com/news/article/skins-now-in-modrinth-app"
},
{
"title": "Creator Updates, July 2025",
"summary": "Addressing recent growth and growing pains that have been affecting creators.",
"thumbnail": "https://modrinth.com/news/default.webp",
"date": "2025-07-02T04:20:00.000Z",
"link": "https://modrinth.com/news/article/creator-updates-july-2025"
},
{
"title": "A Pride Month Success: Over $8,400 Raised for The Trevor Project!",
"summary": "Reflecting on our Pride Month fundraiser campaign for LGBTQ+ youth.",
"thumbnail": "https://modrinth.com/news/article/pride-campaign-2025/thumbnail.webp",
"date": "2025-07-01T18:00:00.000Z",
"link": "https://modrinth.com/news/article/pride-campaign-2025"
},
{
"title": "A New Chapter for Modrinth Servers",
"summary": "Modrinth Servers is now fully operated in-house by the Modrinth Team.",
"thumbnail": "https://modrinth.com/news/article/a-new-chapter-for-modrinth-servers/thumbnail.webp",
"date": "2025-03-13T00:00:00.000Z",
"link": "https://modrinth.com/news/article/a-new-chapter-for-modrinth-servers"
},
{
"title": "Host your own server with Modrinth Servers — now in beta",
"summary": "Fast, simple, reliable servers directly integrated into Modrinth.",
"thumbnail": "https://modrinth.com/news/article/modrinth-servers-beta/thumbnail.webp",
"date": "2024-11-03T06:00:00.000Z",
"link": "https://modrinth.com/news/article/modrinth-servers-beta"
},
{
"title": "Quintupling Creator Revenue and Becoming Sustainable",
"summary": "Announcing an update to our monetization program, creator split, and more!",
"thumbnail": "https://modrinth.com/news/article/becoming-sustainable/thumbnail.webp",
"date": "2024-09-13T20:00:00.000Z",
"link": "https://modrinth.com/news/article/becoming-sustainable"
},
{
"title": "Introducing Modrinth+, a refreshed site look, and a new advertising system!",
"summary": "Learn about this major update to Modrinth.",
"thumbnail": "https://modrinth.com/news/article/design-refresh/thumbnail.webp",
"date": "2024-08-21T20:00:00.000Z",
"link": "https://modrinth.com/news/article/design-refresh"
},
{
"title": "Malware Discovery Disclosure: \"Windows Borderless\" mod",
"summary": "Threat Analysis and Plan of Action",
"thumbnail": "https://modrinth.com/news/article/windows-borderless-malware-disclosure/thumbnail.webp",
"date": "2024-05-07T20:00:00.000Z",
"link": "https://modrinth.com/news/article/windows-borderless-malware-disclosure"
},
{
"title": "A Sustainable Path Forward for Modrinth",
"summary": "Our capital return and whats next.",
"thumbnail": "https://modrinth.com/news/default.webp",
"date": "2024-04-04T20:00:00.000Z",
"link": "https://modrinth.com/news/article/capital-return"
},
{
"title": "Creator Update: Analytics, Organizations, Collections, and more",
"summary": "December may be over, but were not done giving gifts.",
"thumbnail": "https://modrinth.com/news/article/creator-update/thumbnail.webp",
"date": "2024-01-06T20:00:00.000Z",
"link": "https://modrinth.com/news/article/creator-update"
},
{
"title": "Correcting Inflated Download Counts due to Rate Limiting Issue",
"summary": "A rate limiting issue caused inflated download counts in certain countries.",
"thumbnail": "https://modrinth.com/news/default.webp",
"date": "2023-11-10T20:00:00.000Z",
"link": "https://modrinth.com/news/article/download-adjustment"
},
{
"title": "Introducing Modrinth App Beta",
"summary": "Changing the modded Minecraft landscape with the new Modrinth App, alongside several other major features.",
"thumbnail": "https://modrinth.com/news/default.webp",
"date": "2023-08-05T20:00:00.000Z",
"link": "https://modrinth.com/news/article/modrinth-app-beta"
},
{
"title": "(April Fools 2023) Powering up your experience: Modrinth Technologies™ beta launch!",
"summary": "Welcome to the new era of Modrinth. We can't wait to hear your feedback.",
"thumbnail": "https://modrinth.com/news/article/new-site-beta/thumbnail.webp",
"date": "2023-04-01T08:00:00.000Z",
"link": "https://modrinth.com/news/article/new-site-beta"
},
{
"title": "Accelerating Modrinth's Development",
"summary": "Our fundraiser and the future of Modrinth!",
"thumbnail": "https://modrinth.com/news/default.webp",
"date": "2023-02-01T20:00:00.000Z",
"link": "https://modrinth.com/news/article/accelerating-development"
},
{
"title": "Modrinth's Anniversary Update",
"summary": "Marking two years of Modrinth and discussing our New Year's Resolutions for 2023.",
"thumbnail": "https://modrinth.com/news/article/two-years-of-modrinth/thumbnail.webp",
"date": "2023-01-07T00:00:00.000Z",
"link": "https://modrinth.com/news/article/two-years-of-modrinth"
},
{
"title": "Two years of Modrinth: a retrospective",
"summary": "The history of Modrinth as we know it from December 2020 to December 2022.",
"thumbnail": "https://modrinth.com/news/default.webp",
"date": "2023-01-07T00:00:00.000Z",
"link": "https://modrinth.com/news/article/two-years-of-modrinth-history"
},
{
"title": "Creators can now make money on Modrinth!",
"summary": "Introducing the Creator Monetization Program allowing creators to earn revenue from their projects.",
"thumbnail": "https://modrinth.com/news/article/creator-monetization/thumbnail.webp",
"date": "2022-11-12T00:00:00.000Z",
"link": "https://modrinth.com/news/article/creator-monetization"
},
{
"title": "Modrinth's Carbon Ads experiment",
"summary": "Experimenting with a different ad providers to find one which one works for us.",
"thumbnail": "https://modrinth.com/news/article/carbon-ads/thumbnail.webp",
"date": "2022-09-08T00:00:00.000Z",
"link": "https://modrinth.com/news/article/carbon-ads"
},
{
"title": "Plugins and Resource Packs now have a home on Modrinth",
"summary": "A small update with a big impact: plugins and resource packs are now available on Modrinth!",
"thumbnail": "https://modrinth.com/news/article/plugins-resource-packs/thumbnail.webp",
"date": "2022-08-27T00:00:00.000Z",
"link": "https://modrinth.com/news/article/plugins-resource-packs"
},
{
"title": "Changes to Modrinth Modpacks",
"summary": "CurseForge CDN links requested to be removed by the end of the month",
"thumbnail": "https://modrinth.com/news/article/modpack-changes/thumbnail.webp",
"date": "2022-05-28T00:00:00.000Z",
"link": "https://modrinth.com/news/article/modpack-changes"
},
{
"title": "Modrinth Modpacks: Now in alpha testing",
"summary": "After over a year of development, we're happy to announce that modpack support is now in alpha testing.",
"thumbnail": "https://modrinth.com/news/article/modpacks-alpha/thumbnail.webp",
"date": "2022-05-15T00:00:00.000Z",
"link": "https://modrinth.com/news/article/modpacks-alpha"
},
{
"title": "This week in Modrinth development: Filters and Fixes",
"summary": "Continuing to improve the user interface after a great first week since Modrinth launched out of beta.",
"thumbnail": "https://modrinth.com/news/article/knossos-v2.1.0/thumbnail.webp",
"date": "2022-03-09T00:00:00.000Z",
"link": "https://modrinth.com/news/article/knossos-v2.1.0"
},
{
"title": "Now showing on Modrinth: A new look!",
"summary": "Releasing many new features and improvements, including a redesign!",
"thumbnail": "https://modrinth.com/news/article/redesign/thumbnail.webp",
"date": "2022-02-27T00:00:00.000Z",
"link": "https://modrinth.com/news/article/redesign"
},
{
"title": "Beginner's Guide to Licensing your Mods",
"summary": "Software licenses; the nitty-gritty legal aspect of software development. They're more important than you think.",
"thumbnail": "https://modrinth.com/news/article/licensing-guide/thumbnail.webp",
"date": "2021-05-16T00:00:00.000Z",
"link": "https://modrinth.com/news/article/licensing-guide"
},
{
"title": "Welcome to Modrinth Beta",
"summary": "After six months of work, Modrinth enters Beta, helping modders host their mods with ease!",
"thumbnail": "https://modrinth.com/news/article/modrinth-beta/thumbnail.webp",
"date": "2020-12-01T00:00:00.000Z",
"link": "https://modrinth.com/news/article/modrinth-beta"
},
{
"title": "What is Modrinth?",
"summary": "Hello, we are Modrinth an open source mods hosting platform. Sounds dry, doesn't it? So let me tell you our story and I promise, it won't be boring!",
"thumbnail": "https://modrinth.com/news/default.webp",
"date": "2020-11-27T00:00:00.000Z",
"link": "https://modrinth.com/news/article/whats-modrinth"
}
]
"articles": [
{
"title": "Skins — Now in Modrinth App!",
"summary": "Customize your look, save your favorite skins, and swap them out in a flash, all within Modrinth App.",
"thumbnail": "https://modrinth.com/news/article/skins-now-in-modrinth-app/thumbnail.webp",
"date": "2025-07-06T23:45:00.000Z",
"link": "https://modrinth.com/news/article/skins-now-in-modrinth-app"
},
{
"title": "Creator Updates, July 2025",
"summary": "Addressing recent growth and growing pains that have been affecting creators.",
"thumbnail": "https://modrinth.com/news/default.webp",
"date": "2025-07-02T04:20:00.000Z",
"link": "https://modrinth.com/news/article/creator-updates-july-2025"
},
{
"title": "A Pride Month Success: Over $8,400 Raised for The Trevor Project!",
"summary": "Reflecting on our Pride Month fundraiser campaign for LGBTQ+ youth.",
"thumbnail": "https://modrinth.com/news/article/pride-campaign-2025/thumbnail.webp",
"date": "2025-07-01T18:00:00.000Z",
"link": "https://modrinth.com/news/article/pride-campaign-2025"
},
{
"title": "A New Chapter for Modrinth Servers",
"summary": "Modrinth Servers is now fully operated in-house by the Modrinth Team.",
"thumbnail": "https://modrinth.com/news/article/a-new-chapter-for-modrinth-servers/thumbnail.webp",
"date": "2025-03-13T00:00:00.000Z",
"link": "https://modrinth.com/news/article/a-new-chapter-for-modrinth-servers"
},
{
"title": "Host your own server with Modrinth Servers — now in beta",
"summary": "Fast, simple, reliable servers directly integrated into Modrinth.",
"thumbnail": "https://modrinth.com/news/article/modrinth-servers-beta/thumbnail.webp",
"date": "2024-11-03T06:00:00.000Z",
"link": "https://modrinth.com/news/article/modrinth-servers-beta"
},
{
"title": "Quintupling Creator Revenue and Becoming Sustainable",
"summary": "Announcing an update to our monetization program, creator split, and more!",
"thumbnail": "https://modrinth.com/news/article/becoming-sustainable/thumbnail.webp",
"date": "2024-09-13T20:00:00.000Z",
"link": "https://modrinth.com/news/article/becoming-sustainable"
},
{
"title": "Introducing Modrinth+, a refreshed site look, and a new advertising system!",
"summary": "Learn about this major update to Modrinth.",
"thumbnail": "https://modrinth.com/news/article/design-refresh/thumbnail.webp",
"date": "2024-08-21T20:00:00.000Z",
"link": "https://modrinth.com/news/article/design-refresh"
},
{
"title": "Malware Discovery Disclosure: \"Windows Borderless\" mod",
"summary": "Threat Analysis and Plan of Action",
"thumbnail": "https://modrinth.com/news/article/windows-borderless-malware-disclosure/thumbnail.webp",
"date": "2024-05-07T20:00:00.000Z",
"link": "https://modrinth.com/news/article/windows-borderless-malware-disclosure"
},
{
"title": "A Sustainable Path Forward for Modrinth",
"summary": "Our capital return and whats next.",
"thumbnail": "https://modrinth.com/news/default.webp",
"date": "2024-04-04T20:00:00.000Z",
"link": "https://modrinth.com/news/article/capital-return"
},
{
"title": "Creator Update: Analytics, Organizations, Collections, and more",
"summary": "December may be over, but were not done giving gifts.",
"thumbnail": "https://modrinth.com/news/article/creator-update/thumbnail.webp",
"date": "2024-01-06T20:00:00.000Z",
"link": "https://modrinth.com/news/article/creator-update"
},
{
"title": "Correcting Inflated Download Counts due to Rate Limiting Issue",
"summary": "A rate limiting issue caused inflated download counts in certain countries.",
"thumbnail": "https://modrinth.com/news/default.webp",
"date": "2023-11-10T20:00:00.000Z",
"link": "https://modrinth.com/news/article/download-adjustment"
},
{
"title": "Introducing Modrinth App Beta",
"summary": "Changing the modded Minecraft landscape with the new Modrinth App, alongside several other major features.",
"thumbnail": "https://modrinth.com/news/default.webp",
"date": "2023-08-05T20:00:00.000Z",
"link": "https://modrinth.com/news/article/modrinth-app-beta"
},
{
"title": "(April Fools 2023) Powering up your experience: Modrinth Technologies™ beta launch!",
"summary": "Welcome to the new era of Modrinth. We can't wait to hear your feedback.",
"thumbnail": "https://modrinth.com/news/article/new-site-beta/thumbnail.webp",
"date": "2023-04-01T08:00:00.000Z",
"link": "https://modrinth.com/news/article/new-site-beta"
},
{
"title": "Accelerating Modrinth's Development",
"summary": "Our fundraiser and the future of Modrinth!",
"thumbnail": "https://modrinth.com/news/default.webp",
"date": "2023-02-01T20:00:00.000Z",
"link": "https://modrinth.com/news/article/accelerating-development"
},
{
"title": "Modrinth's Anniversary Update",
"summary": "Marking two years of Modrinth and discussing our New Year's Resolutions for 2023.",
"thumbnail": "https://modrinth.com/news/article/two-years-of-modrinth/thumbnail.webp",
"date": "2023-01-07T00:00:00.000Z",
"link": "https://modrinth.com/news/article/two-years-of-modrinth"
},
{
"title": "Two years of Modrinth: a retrospective",
"summary": "The history of Modrinth as we know it from December 2020 to December 2022.",
"thumbnail": "https://modrinth.com/news/default.webp",
"date": "2023-01-07T00:00:00.000Z",
"link": "https://modrinth.com/news/article/two-years-of-modrinth-history"
},
{
"title": "Creators can now make money on Modrinth!",
"summary": "Introducing the Creator Monetization Program allowing creators to earn revenue from their projects.",
"thumbnail": "https://modrinth.com/news/article/creator-monetization/thumbnail.webp",
"date": "2022-11-12T00:00:00.000Z",
"link": "https://modrinth.com/news/article/creator-monetization"
},
{
"title": "Modrinth's Carbon Ads experiment",
"summary": "Experimenting with a different ad providers to find one which one works for us.",
"thumbnail": "https://modrinth.com/news/article/carbon-ads/thumbnail.webp",
"date": "2022-09-08T00:00:00.000Z",
"link": "https://modrinth.com/news/article/carbon-ads"
},
{
"title": "Plugins and Resource Packs now have a home on Modrinth",
"summary": "A small update with a big impact: plugins and resource packs are now available on Modrinth!",
"thumbnail": "https://modrinth.com/news/article/plugins-resource-packs/thumbnail.webp",
"date": "2022-08-27T00:00:00.000Z",
"link": "https://modrinth.com/news/article/plugins-resource-packs"
},
{
"title": "Changes to Modrinth Modpacks",
"summary": "CurseForge CDN links requested to be removed by the end of the month",
"thumbnail": "https://modrinth.com/news/article/modpack-changes/thumbnail.webp",
"date": "2022-05-28T00:00:00.000Z",
"link": "https://modrinth.com/news/article/modpack-changes"
},
{
"title": "Modrinth Modpacks: Now in alpha testing",
"summary": "After over a year of development, we're happy to announce that modpack support is now in alpha testing.",
"thumbnail": "https://modrinth.com/news/article/modpacks-alpha/thumbnail.webp",
"date": "2022-05-15T00:00:00.000Z",
"link": "https://modrinth.com/news/article/modpacks-alpha"
},
{
"title": "This week in Modrinth development: Filters and Fixes",
"summary": "Continuing to improve the user interface after a great first week since Modrinth launched out of beta.",
"thumbnail": "https://modrinth.com/news/article/knossos-v2.1.0/thumbnail.webp",
"date": "2022-03-09T00:00:00.000Z",
"link": "https://modrinth.com/news/article/knossos-v2.1.0"
},
{
"title": "Now showing on Modrinth: A new look!",
"summary": "Releasing many new features and improvements, including a redesign!",
"thumbnail": "https://modrinth.com/news/article/redesign/thumbnail.webp",
"date": "2022-02-27T00:00:00.000Z",
"link": "https://modrinth.com/news/article/redesign"
},
{
"title": "Beginner's Guide to Licensing your Mods",
"summary": "Software licenses; the nitty-gritty legal aspect of software development. They're more important than you think.",
"thumbnail": "https://modrinth.com/news/article/licensing-guide/thumbnail.webp",
"date": "2021-05-16T00:00:00.000Z",
"link": "https://modrinth.com/news/article/licensing-guide"
},
{
"title": "Welcome to Modrinth Beta",
"summary": "After six months of work, Modrinth enters Beta, helping modders host their mods with ease!",
"thumbnail": "https://modrinth.com/news/article/modrinth-beta/thumbnail.webp",
"date": "2020-12-01T00:00:00.000Z",
"link": "https://modrinth.com/news/article/modrinth-beta"
},
{
"title": "What is Modrinth?",
"summary": "Hello, we are Modrinth an open source mods hosting platform. Sounds dry, doesn't it? So let me tell you our story and I promise, it won't be boring!",
"thumbnail": "https://modrinth.com/news/default.webp",
"date": "2020-11-27T00:00:00.000Z",
"link": "https://modrinth.com/news/article/whats-modrinth"
}
]
}

View File

@@ -1,11 +1,14 @@
<?xml version="1.0" encoding="UTF-8"?>
<OpenSearchDescription xmlns="http://a9.com/-/spec/opensearch/1.1/" xmlns:moz="http://www.mozilla.org/2006/browser/search/">
<ShortName>Modrinth mods</ShortName>
<Description>Search for mods on Modrinth, the open source modding platform.</Description>
<InputEncoding>UTF-8</InputEncoding>
<Image width="16" height="16" type="image/x-icon">https://modrinth.com/favicon.ico</Image>
<Url type="text/html" method="get" template="https://modrinth.com/mods?q={searchTerms}"/>
<Developer>Rinth, Inc.</Developer>
<Attribution>Rinth, Inc.</Attribution>
<moz:SearchForm>https://modrinth.com/mods</moz:SearchForm>
<?xml version="1.0" encoding="UTF-8" ?>
<OpenSearchDescription
xmlns="http://a9.com/-/spec/opensearch/1.1/"
xmlns:moz="http://www.mozilla.org/2006/browser/search/"
>
<ShortName>Modrinth mods</ShortName>
<Description>Search for mods on Modrinth, the open source modding platform.</Description>
<InputEncoding>UTF-8</InputEncoding>
<Image width="16" height="16" type="image/x-icon">https://modrinth.com/favicon.ico</Image>
<Url type="text/html" method="get" template="https://modrinth.com/mods?q={searchTerms}" />
<Developer>Rinth, Inc.</Developer>
<Attribution>Rinth, Inc.</Attribution>
<moz:SearchForm>https://modrinth.com/mods</moz:SearchForm>
</OpenSearchDescription>

View File

@@ -0,0 +1,119 @@
**/*.rs
**/*.svg
.sqlx
# Migrations existing before Prettier formatted them shall always be ignored,
# as any changes to them will break existing deployments
migrations/20200716160921_init.sql
migrations/20200717192808_Make_categories_non-null.sql
migrations/20200722031742_initial-release-channels.sql
migrations/20200722033157_rename-release-channels.sql
migrations/20200722153930_version-filename.sql
migrations/20200730223151_more-not-null.sql
migrations/20200812183213_unique-loaders.sql
migrations/20200928020509_states.sql
migrations/20200928033759_edit-states.sql
migrations/20200928053955_make-url-not-null.sql
migrations/20200928170310_create-users.sql
migrations/20200928195220_add-roles-to-users.sql
migrations/20200929034101_add-author-to-versions.sql
migrations/20201001015631_not-null-github-avatar.sql
migrations/20201003211651_make-name-null.sql
migrations/20201014165954_create-statuses.sql
migrations/20201021214908_extend-game-version.sql
migrations/20201029190804_add-game-version-datetime.sql
migrations/20201109200208_edit-teams.sql
migrations/20201112052516_moderation.sql
migrations/20201122043349_more-mod-data.sql
migrations/20201213013358_remove-member-name.sql
migrations/20210113202021_add-descriptions.sql
migrations/20210118161307_remove-version-access.sql
migrations/20210129224854_dependency-types.sql
migrations/20210201001429_reports.sql
migrations/20210224174945_notifications.sql
migrations/20210301041252_follows.sql
migrations/20210509010206_project_types.sql
migrations/20210611024943_archived-status-notifications-icon-rejection-reasons.sql
migrations/20210718223710_gallery.sql
migrations/20210727160151_gallery_featuring_rejection_rename.sql
migrations/20210805044459_more_gallery_info.sql
migrations/20210820053031_version-optimization.sql
migrations/20220210032959_remove-categories-unique.sql
migrations/20220220035037_remove_downloads_table.sql
migrations/20220329182356_file-sizes.sql
migrations/20220526040434_dep-file-names.sql
migrations/20220725204351_more-project-data.sql
migrations/20220801184215_banned-users.sql
migrations/20220902025606_initial-payouts.sql
migrations/20220928044123_payouts-scheduling.sql
migrations/20221107171016_payouts-overhaul.sql
migrations/20221111163753_fix-precision.sql
migrations/20221111202802_fix-precision-again.sql
migrations/20221116200727_flame-anvil-integration.sql
migrations/20221126222222_spdx-licenses.sql
migrations/20221129161609_status-types-changes.sql
migrations/20221206221021_webhook-sent.sql
migrations/20221217041358_ordering-galore.sql
migrations/20221217215337_drop-body_url-changelog_url.sql
migrations/20221223192812_file-labels.sql
migrations/20221227010515_project-colors.sql
migrations/20230104214503_random-projects.sql
migrations/20230127233123_loader-gv-mod.sql
migrations/20230221212958_queue-date.sql
migrations/20230324202117_messaging.sql
migrations/20230414203933_threads-fix.sql
migrations/20230416033024_deps-project-mandatory.sql
migrations/20230421174120_remove-threads-ref.sql
migrations/20230502141522_minos-support.sql
migrations/20230628180115_kill-ory.sql
migrations/20230710034250_flows.sql
migrations/20230711004131_2fa.sql
migrations/20230714235551_fix-2fa-type.sql
migrations/20230808043323_threads-index.sql
migrations/20230808162652_gv-loader-fixes.sql
migrations/20230816085700_collections_and_more.sql
migrations/20230913024611_organizations.sql
migrations/20231005230721_dynamic-fields.sql
migrations/20231016190056_oauth_provider.sql
migrations/20231027195838_version_ordering.sql
migrations/20231110010322_adds_game_version_minmax.sql
migrations/20231113104902_games_metadata.sql
migrations/20231114175920_new-payment-methods.sql
migrations/20231115105022_plugins_datapacks_v3.sql
migrations/20231116112800_side_types_overhaul.sql
migrations/20231117073600_links_overhaul.sql
migrations/20231122230639_oauth_client_metadata.sql
migrations/20231124070100_renaming_consistency.sql
migrations/20231125080100_drops_mods_dp_plugins.sql
migrations/20231130153100_loader_fields_loaders.sql
migrations/20231205095400_remaining_loader_field_loaders.sql
migrations/20231211184922_collections_description_nullable.sql
migrations/20231213103100_enforces-owner-unique.sql
migrations/20240104203711_orgs-names.sql
migrations/20240115052708_base62-helper-functions.sql
migrations/20240131224610_moderation_packs.sql
migrations/20240221215354_moderation_pack_fixes.sql
migrations/20240319195753_threads-updates.sql
migrations/20240701213559_remove-user-names.sql
migrations/20240702213250_subscriptions.sql
migrations/20240907192840_raw-images.sql
migrations/20240911044738_payouts-updates.sql
migrations/20240923163452_charges-fix.sql
migrations/20241121232522_friends.sql
migrations/20241204190127_revenue_updates.sql
migrations/20241224001114_teams-precision-fix.sql
migrations/20250117013050_missing-primary-keys.sql
migrations/20250519184051_shared-instances.sql
migrations/20250523174544_project-versions-environments.sql
migrations/20250608183828_random-project-index.sql
migrations/20250609134334_spatial-random-project-index.sql
migrations/20250611164523_lowercase-user-email-index.sql
migrations/20250628213541_payout-sources-recording.sql
migrations/20250725230041_reports-closed-status-index.sql
migrations/20250727184120_user-newsletter-subscription-column.sql
migrations/20250804221014_users-redeemals.sql
migrations/20250805001654_product-prices-public.sql
# Prettier reformats some of the PostgreSQL-specific COPY syntax here,
# which is very likely to break things
fixtures/labrinth-seed-data-202508052143.sql

View File

@@ -76,19 +76,16 @@ thiserror.workspace = true
either.workspace = true
sqlx = { workspace = true, features = [
"runtime-tokio",
"tls-rustls-ring",
"postgres",
"chrono",
"macros",
"migrate",
"rust_decimal",
"json",
] }
rust_decimal = { workspace = true, features = [
"serde-with-float",
"serde-with-str",
"runtime-tokio",
"tls-rustls-ring",
"postgres",
"chrono",
"macros",
"migrate",
"rust_decimal",
"json",
] }
rust_decimal = { workspace = true, features = ["serde-with-float", "serde-with-str"] }
redis = { workspace = true, features = ["tokio-comp", "ahash", "r2d2"] }
deadpool-redis.workspace = true
clickhouse = { workspace = true, features = ["uuid", "time"] }
@@ -101,7 +98,23 @@ tar.workspace = true
sentry.workspace = true
sentry-actix.workspace = true
image = { workspace = true, features = ["avif", "bmp", "dds", "exr", "ff", "gif", "hdr", "ico", "jpeg", "png", "pnm", "qoi", "tga", "tiff", "webp"] }
image = { workspace = true, features = [
"avif",
"bmp",
"dds",
"exr",
"ff",
"gif",
"hdr",
"ico",
"jpeg",
"png",
"pnm",
"qoi",
"tga",
"tiff",
"webp",
] }
color-thief.workspace = true
webp.workspace = true
@@ -120,7 +133,10 @@ ariadne.workspace = true
clap = { workspace = true, features = ["derive"] }
[target.'cfg(target_os = "linux")'.dependencies]
tikv-jemallocator = { workspace = true, features = ["profiling", "unprefixed_malloc_on_supported_platforms"] }
tikv-jemallocator = { workspace = true, features = [
"profiling",
"unprefixed_malloc_on_supported_platforms",
] }
tikv-jemalloc-ctl = { workspace = true, features = ["stats"] }
jemalloc_pprof = { workspace = true, features = ["flamegraph"] }

View File

@@ -1,78 +1,78 @@
:root {
--color-bg: #16181c;
--color-fg: #b0bac5;
--color-section-bg: #26292f;
--color-bg: #16181c;
--color-fg: #b0bac5;
--color-section-bg: #26292f;
--content-width: 30%;
--content-max-width: 300px;
--content-padding: 1.5rem;
--edge-rounding: 1rem;
--content-width: 30%;
--content-max-width: 300px;
--content-padding: 1.5rem;
--edge-rounding: 1rem;
}
html,
body {
height: 100%;
overflow: hidden;
height: 100%;
overflow: hidden;
}
body {
color: var(--color-fg);
background-color: var(--color-bg);
display: flex;
justify-content: center;
align-items: center;
font-family:
Inter,
-apple-system,
BlinkMacSystemFont,
'Segoe UI',
Helvetica Neue,
Helvetica,
Oxygen,
Ubuntu,
Roboto,
Cantarell,
Fira Sans,
Droid Sans,
'Apple Color Emoji',
'Segoe UI Emoji',
Arial,
sans-serif;
color: var(--color-fg);
background-color: var(--color-bg);
display: flex;
justify-content: center;
align-items: center;
font-family:
Inter,
-apple-system,
BlinkMacSystemFont,
'Segoe UI',
Helvetica Neue,
Helvetica,
Oxygen,
Ubuntu,
Roboto,
Cantarell,
Fira Sans,
Droid Sans,
'Apple Color Emoji',
'Segoe UI Emoji',
Arial,
sans-serif;
}
.content {
background-color: var(--color-section-bg);
width: var(--content-width);
max-width: var(--content-max-width);
border-radius: var(--edge-rounding);
padding: var(--content-padding);
justify-content: center;
align-items: center;
box-sizing: border-box;
background-color: var(--color-section-bg);
width: var(--content-width);
max-width: var(--content-max-width);
border-radius: var(--edge-rounding);
padding: var(--content-padding);
justify-content: center;
align-items: center;
box-sizing: border-box;
}
.content h2 {
margin-bottom: 0;
margin-bottom: 0;
}
.logo {
display: block;
width: 100%;
margin-left: auto;
margin-right: auto;
margin-bottom: 2rem;
border-radius: 1.5rem;
display: block;
width: 100%;
margin-left: auto;
margin-right: auto;
margin-bottom: 2rem;
border-radius: 1.5rem;
}
a {
color: #4f9cff;
text-decoration: underline;
color: #4f9cff;
text-decoration: underline;
}
a:visited {
color: #4f9cff;
color: #4f9cff;
}
img {
image-rendering: pixelated;
image-rendering: pixelated;
}

View File

@@ -1,14 +1,17 @@
{
"name": "@modrinth/labrinth",
"scripts": {
"build": "cargo build --release",
"lint": "cargo fmt --check && cargo clippy --all-targets",
"fix": "cargo clippy --all-targets --fix --allow-dirty && cargo fmt",
"dev": "cargo run",
"//": "labrinth integration tests require a lot of disk space, so in the standard GitHub Actions",
"//": "runners we must remove useless development tools from the base image, which frees up ~20 GiB.",
"//": "The command commented out below can be used in CI to debug what is taking up space:",
"//": "sudo du -xh --max-depth=4 / | sort -rh | curl -X POST --data-urlencode content@/dev/fd/0 https://api.mclo.gs/1/log",
"test": "if-ci sudo rm -rf /usr/local/lib/android /usr/local/.ghcup /opt/hostedtoolcache/CodeQL /usr/share/swift && cargo nextest run --all-targets --no-fail-fast"
}
"name": "@modrinth/labrinth",
"scripts": {
"build": "cargo build --release",
"lint": "cargo fmt --check && cargo clippy --all-targets",
"lint:ancillary": "prettier --check .",
"fix": "cargo clippy --all-targets --fix --allow-dirty && cargo fmt",
"fix:ancillary": "prettier --write .",
"dev": "cargo run",
"//": "labrinth integration tests require a lot of disk space, so in the standard GitHub Actions",
"//": "runners we must remove useless development tools from the base image, which frees up ~20 GiB.",
"//": "The command commented out below can be used in CI to debug what is taking up space:",
"//": "sudo du -xh --max-depth=4 / | sort -rh | curl -X POST --data-urlencode content@/dev/fd/0 https://api.mclo.gs/1/log",
"test": "if-ci sudo rm -rf /usr/local/lib/android /usr/local/.ghcup /opt/hostedtoolcache/CodeQL /usr/share/swift && cargo nextest run --all-targets --no-fail-fast"
},
"prettier": "@modrinth/tooling-config/labrinth.prettier.config.cjs"
}

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@@ -1,22 +1,22 @@
<!doctype html>
<html lang="en">
<head>
<link rel="stylesheet" href="/auth/style.css" />
<link rel="icon" type="image/png" href="/favicon.ico" />
<title>Error - Modrinth</title>
</head>
<head>
<link rel="stylesheet" href="/auth/style.css" />
<link rel="icon" type="image/png" href="/favicon.ico" />
<title>Error - Modrinth</title>
</head>
<body>
<div class="content">
<img src="/logo.svg" alt="Modrinth Logo" class="logo" />
<h2>{{ code }}</h2>
<p>An error has occurred during the authentication process.</p>
<p>
Try closing this window and signing in again. Join
<a href="https://discord.modrinth.com">our Discord server</a> to get help if this error
persists after three attempts.
</p>
<p><b>Debug information:</b> {{ message }}</p>
</div>
</body>
<body>
<div class="content">
<img src="/logo.svg" alt="Modrinth Logo" class="logo" />
<h2>{{ code }}</h2>
<p>An error has occurred during the authentication process.</p>
<p>
Try closing this window and signing in again. Join
<a href="https://discord.modrinth.com">our Discord server</a> to get help if this error
persists after three attempts.
</p>
<p><b>Debug information:</b> {{ message }}</p>
</div>
</body>
</html>

View File

@@ -1,16 +1,16 @@
<!doctype html>
<html lang="en">
<head>
<link rel="stylesheet" href="/auth/style.css" />
<link rel="icon" type="image/png" href="/favicon.ico" />
<title>Login - Modrinth</title>
</head>
<head>
<link rel="stylesheet" href="/auth/style.css" />
<link rel="icon" type="image/png" href="/favicon.ico" />
<title>Login - Modrinth</title>
</head>
<body>
<div class="content">
<img src="{{ icon }}" alt="{{ name }}" class="logo" />
<h2>Login Successful</h2>
<p>Hey, {{ name }}! You can now safely close this tab.</p>
</div>
</body>
<body>
<div class="content">
<img src="{{ icon }}" alt="{{ name }}" class="logo" />
<h2>Login Successful</h2>
<p>Hey, {{ name }}! You can now safely close this tab.</p>
</div>
</body>
</html>

View File

@@ -5,10 +5,13 @@
-- 'Friend' and 'enemy' function like 'user', but we can use them to simulate 'other' users that may or may not be able to access certain things
-- IDs 1-5, 1-5
INSERT INTO users (id, username, email, role) VALUES (1, 'Admin', 'admin@modrinth.com', 'admin');
INSERT INTO users (id, username, email, role) VALUES (2, 'Moderator', 'moderator@modrinth.com', 'moderator');
INSERT INTO users (id, username, email, role)
VALUES (2, 'Moderator', 'moderator@modrinth.com', 'moderator');
INSERT INTO users (id, username, email, role) VALUES (3, 'User', 'user@modrinth.com', 'developer');
INSERT INTO users (id, username, email, role) VALUES (4, 'Friend', 'friend@modrinth.com', 'developer');
INSERT INTO users (id, username, email, role) VALUES (5, 'Enemy', 'enemy@modrinth.com', 'developer');
INSERT INTO users (id, username, email, role)
VALUES (4, 'Friend', 'friend@modrinth.com', 'developer');
INSERT INTO users (id, username, email, role)
VALUES (5, 'Enemy', 'enemy@modrinth.com', 'developer');
-- Full PATs for each user, with different scopes
-- These are not legal PATs, as they contain all scopes- they mimic permissions of a logged in user
@@ -20,73 +23,88 @@ INSERT INTO pats (id, user_id, name, access_token, scopes, expires) VALUES (53,
INSERT INTO pats (id, user_id, name, access_token, scopes, expires) VALUES (54, 5, 'enemy-pat', 'mrp_patenemy', $1, '2030-08-18 15:48:58.435729+00');
INSERT INTO loaders (id, loader) VALUES (5, 'fabric');
INSERT INTO loaders_project_types (joining_loader_id, joining_project_type_id) VALUES (5,1);
INSERT INTO loaders_project_types (joining_loader_id, joining_project_type_id) VALUES (5, 1);
INSERT INTO loaders (id, loader) VALUES (6, 'forge');
INSERT INTO loaders_project_types (joining_loader_id, joining_project_type_id) VALUES (6,1);
INSERT INTO loaders_project_types (joining_loader_id, joining_project_type_id) VALUES (6, 1);
INSERT INTO loaders (id, loader, metadata) VALUES (7, 'bukkit', '{"platform":false}'::jsonb);
INSERT INTO loaders (id, loader, metadata) VALUES (8, 'waterfall', '{"platform":true}'::jsonb);
INSERT INTO loaders (id, loader, metadata) VALUES (7, 'bukkit', '{"platform":false}'::JSONB);
INSERT INTO loaders (id, loader, metadata) VALUES (8, 'waterfall', '{"platform":true}'::JSONB);
-- Adds dummies to mrpack_loaders
INSERT INTO loader_field_enum_values (enum_id, value) SELECT id, 'fabric' FROM loader_field_enums WHERE enum_name = 'mrpack_loaders';
INSERT INTO loader_field_enum_values (enum_id, value) SELECT id, 'forge' FROM loader_field_enums WHERE enum_name = 'mrpack_loaders';
INSERT INTO loader_field_enum_values (enum_id, value)
SELECT id, 'fabric' FROM loader_field_enums WHERE enum_name = 'mrpack_loaders';
INSERT INTO loader_field_enum_values (enum_id, value)
SELECT id, 'forge' FROM loader_field_enums WHERE enum_name = 'mrpack_loaders';
INSERT INTO loaders_project_types_games (loader_id, project_type_id, game_id) SELECT joining_loader_id, joining_project_type_id, 1 FROM loaders_project_types WHERE joining_loader_id = 5;
INSERT INTO loaders_project_types_games (loader_id, project_type_id, game_id) SELECT joining_loader_id, joining_project_type_id, 1 FROM loaders_project_types WHERE joining_loader_id = 6;
INSERT INTO loaders_project_types_games (loader_id, project_type_id, game_id)
SELECT joining_loader_id, joining_project_type_id, 1
FROM loaders_project_types
WHERE joining_loader_id = 5;
INSERT INTO loaders_project_types_games (loader_id, project_type_id, game_id)
SELECT joining_loader_id, joining_project_type_id, 1
FROM loaders_project_types
WHERE joining_loader_id = 6;
-- Dummy-data only optional field, as we don't have any yet
INSERT INTO loader_fields (
field,
field_type,
optional
) VALUES (
'test_fabric_optional',
'integer',
true
);
INSERT INTO loader_fields_loaders(loader_id, loader_field_id)
SELECT l.id, lf.id FROM loaders l CROSS JOIN loader_fields lf WHERE lf.field = 'test_fabric_optional' AND l.loader = 'fabric' ON CONFLICT DO NOTHING;
INSERT INTO loader_fields
(field, field_type, optional)
VALUES
('test_fabric_optional', 'integer', TRUE);
INSERT INTO loader_fields_loaders (loader_id, loader_field_id)
SELECT l.id, lf.id
FROM
loaders AS l
CROSS JOIN loader_fields AS lf
WHERE lf.field = 'test_fabric_optional' AND l.loader = 'fabric'
ON CONFLICT DO NOTHING;
-- Sample game versions, loaders, categories
-- Game versions is '2'
INSERT INTO loader_field_enum_values(enum_id, value, metadata, created)
INSERT INTO loader_field_enum_values (enum_id, value, metadata, created)
VALUES (2, '1.20.1', '{"type":"release","major":false}', '2021-08-18 15:48:58.435729+00');
INSERT INTO loader_field_enum_values(enum_id, value, metadata, created)
INSERT INTO loader_field_enum_values (enum_id, value, metadata, created)
VALUES (2, '1.20.2', '{"type":"release","major":false}', '2021-08-18 15:48:59.435729+00');
INSERT INTO loader_field_enum_values(enum_id, value, metadata, created)
INSERT INTO loader_field_enum_values (enum_id, value, metadata, created)
VALUES (2, '1.20.3', '{"type":"release","major":false}', '2021-08-18 15:49:00.435729+00');
INSERT INTO loader_field_enum_values(enum_id, value, metadata, created)
INSERT INTO loader_field_enum_values (enum_id, value, metadata, created)
VALUES (2, '1.20.4', '{"type":"beta","major":false}', '2021-08-18 15:49:01.435729+00');
INSERT INTO loader_field_enum_values(enum_id, value, metadata, created)
INSERT INTO loader_field_enum_values (enum_id, value, metadata, created)
VALUES (2, '1.20.5', '{"type":"release","major":true}', '2061-08-18 15:49:02.435729+00');
-- Also add 'Ordering_Negative1' and 'Ordering_Positive100' to game versions (to test ordering override)
INSERT INTO loader_field_enum_values(enum_id, value, metadata, ordering)
INSERT INTO loader_field_enum_values (enum_id, value, metadata, ordering)
VALUES (2, 'Ordering_Negative1', '{"type":"release","major":false}', -1);
INSERT INTO loader_field_enum_values(enum_id, value, metadata, ordering)
INSERT INTO loader_field_enum_values (enum_id, value, metadata, ordering)
VALUES (2, 'Ordering_Positive100', '{"type":"release","major":false}', 100);
INSERT INTO loader_fields_loaders(loader_id, loader_field_id)
SELECT l.id, lf.id FROM loaders l CROSS JOIN loader_fields lf WHERE lf.field IN ('game_versions','environment') ON CONFLICT DO NOTHING;
INSERT INTO loader_fields_loaders (loader_id, loader_field_id)
SELECT l.id, lf.id
FROM
loaders AS l
CROSS JOIN loader_fields AS lf
WHERE lf.field IN ('game_versions', 'environment')
ON CONFLICT DO NOTHING;
INSERT INTO categories (id, category, project_type) VALUES
(51, 'combat', 1),
(52, 'decoration', 1),
(53, 'economy', 1),
(54, 'food', 1),
(55, 'magic', 1),
(56, 'mobs', 1),
(57, 'optimization', 1);
INSERT INTO categories (id, category, project_type)
VALUES
(51, 'combat', 1),
(52, 'decoration', 1),
(53, 'economy', 1),
(54, 'food', 1),
(55, 'magic', 1),
(56, 'mobs', 1),
(57, 'optimization', 1);
INSERT INTO categories (id, category, project_type) VALUES
(101, 'combat', 2),
(102, 'decoration', 2),
(103, 'economy', 2),
(104, 'food', 2),
(105, 'magic', 2),
(106, 'mobs', 2),
(107, 'optimization', 2);
INSERT INTO categories (id, category, project_type)
VALUES
(101, 'combat', 2),
(102, 'decoration', 2),
(103, 'economy', 2),
(104, 'food', 2),
(105, 'magic', 2),
(106, 'mobs', 2),
(107, 'optimization', 2);
-- Create dummy oauth client, secret_hash is SHA512 hash of full lowercase alphabet
INSERT INTO oauth_clients (
@@ -105,9 +123,10 @@ VALUES (
'4dbff86cc2ca1bae1e16468a05cb9881c97f1753bce3619034898faa1aabe429955a1bf8ec483d7421fe3c1646613a59ed5441fb0f321389f77f48a879c7b1f1',
3
);
INSERT INTO oauth_client_redirect_uris (id, client_id, uri) VALUES (1, 1, 'https://modrinth.com/oauth_callback');
INSERT INTO oauth_client_redirect_uris (id, client_id, uri)
VALUES (1, 1, 'https://modrinth.com/oauth_callback');
-- Create dummy data table to mark that this file has been run
CREATE TABLE dummy_data (
update_id bigint PRIMARY KEY
);
update_id BIGINT PRIMARY KEY
);