diff --git a/apps/frontend/src/locales/en-US/index.json b/apps/frontend/src/locales/en-US/index.json
index f248bac278..ea7dc53af2 100644
--- a/apps/frontend/src/locales/en-US/index.json
+++ b/apps/frontend/src/locales/en-US/index.json
@@ -2853,43 +2853,43 @@
"message": "URL"
},
"project.settings.permissions.attention-needed.description.proj-approved": {
- "message": "Please provide proof that you have permission to redistribute all of the following files and any withheld versions will be automatically published."
+ "message": "Please provide proof that you have permission to redistribute all of the following files. Once completed, withheld versions will be automatically published."
},
"project.settings.permissions.attention-needed.description.proj-draft": {
- "message": "Please provide proof that you have permission to redistribute all of the following files before you can submit your project for review."
+ "message": "Please provide proof that you have permission to redistribute all of the following files before submitting your project for review."
},
"project.settings.permissions.attention-needed.title": {
- "message": "Unknown embedded content"
+ "message": "Unknown external content"
},
"project.settings.permissions.completed.description": {
- "message": "All external content has attributions provided."
+ "message": "All external content has permission information and attributions have been provided."
},
"project.settings.permissions.completed.title": {
- "message": "Attributions completed!"
+ "message": "Permissions completed!"
},
"project.settings.permissions.empty-state.description": {
- "message": "None of your versions contain external content, so you don't need to worry about obtaining permissions."
+ "message": "None of your project's versions contain external content, so you don't need to worry about obtaining permissions."
},
"project.settings.permissions.empty-state.heading": {
"message": "You're all set!"
},
"project.settings.permissions.fail.description": {
- "message": "You don't have permission to redistribute some of the external content you've added. In order to publish on Modrinth, remove the infringing content or provide proof that you do have permission to use it."
+ "message": "You may not have permission to redistribute some of the external content in your project. In order to publish on Modrinth, please remove this content or provide proof that you do have permission to use it."
},
"project.settings.permissions.fail.title": {
"message": "Some content can't be included"
},
"project.settings.permissions.info-banner.description": {
- "message": "If you include content that isn’t hosted on Modrinth, you need to let us know where it’s from and verify that you have permission to distribute the files. Check out our guide to learn about how to do this properly!"
+ "message": "If you include content that isn’t hosted on Modrinth, you need to let us know where it’s from and verify that you have permission to distribute the files. Check out our guide to learn more and get started!"
},
"project.settings.permissions.info-banner.title": {
- "message": "Learn how attributions work"
+ "message": "Learn about distribution permissions"
},
"project.settings.permissions.learn-more": {
"message": "Learn more"
},
"project.settings.permissions.no-results": {
- "message": "No external projects match your search."
+ "message": "No external files match your search."
},
"project.settings.permissions.search-placeholder": {
"message": "Search {count} {count, plural, one {project} other {projects}}..."
diff --git a/apps/frontend/src/pages/[type]/[project]/settings/permissions.vue b/apps/frontend/src/pages/[type]/[project]/settings/permissions.vue
index 7d6050d778..1fa30cf46e 100644
--- a/apps/frontend/src/pages/[type]/[project]/settings/permissions.vue
+++ b/apps/frontend/src/pages/[type]/[project]/settings/permissions.vue
@@ -187,11 +187,11 @@ const messages = defineMessages({
},
infoBannerTitle: {
id: 'project.settings.permissions.info-banner.title',
- defaultMessage: 'Learn how attributions work',
+ defaultMessage: 'Learn about distribution permissions',
},
infoBannerDescription: {
id: 'project.settings.permissions.info-banner.description',
- defaultMessage: `If you include content that isn’t hosted on Modrinth, you need to let us know where it’s from and verify that you have permission to distribute the files. Check out our guide to learn about how to do this properly!`,
+ defaultMessage: `If you include content that isn’t hosted on Modrinth, you need to let us know where it’s from and verify that you have permission to distribute the files. Check out our guide to learn more and get started!`,
},
learnMore: {
id: 'project.settings.permissions.learn-more',
@@ -203,15 +203,16 @@ const messages = defineMessages({
},
emptyStateDescription: {
id: 'project.settings.permissions.empty-state.description',
- defaultMessage: `None of your versions contain external content, so you don't need to worry about obtaining permissions.`,
+ defaultMessage: `None of your project's versions contain external content, so you don't need to worry about obtaining permissions.`,
},
completedTitle: {
id: 'project.settings.permissions.completed.title',
- defaultMessage: `Attributions completed!`,
+ defaultMessage: `Permissions completed!`,
},
completedDescription: {
id: 'project.settings.permissions.completed.description',
- defaultMessage: 'All external content has attributions provided.',
+ defaultMessage:
+ 'All external content has permission information and attributions have been provided.',
},
failTitle: {
id: 'project.settings.permissions.fail.title',
@@ -219,23 +220,23 @@ const messages = defineMessages({
},
failDescription: {
id: 'project.settings.permissions.fail.description',
- defaultMessage: `You don't have permission to redistribute some of the external content you've added. In order to publish on Modrinth, remove the infringing content or provide proof that you do have permission to use it.`,
+ defaultMessage: `You may not have permission to redistribute some of the external content in your project. In order to publish on Modrinth, please remove this content or provide proof that you do have permission to use it.`,
},
attentionNeededTitle: {
id: 'project.settings.permissions.attention-needed.title',
- defaultMessage: `Unknown embedded content`,
+ defaultMessage: `Unknown external content`,
},
attentionNeededDescriptionApproved: {
id: 'project.settings.permissions.attention-needed.description.proj-approved',
- defaultMessage: `Please provide proof that you have permission to redistribute all of the following files and any withheld versions will be automatically published.`,
+ defaultMessage: `Please provide proof that you have permission to redistribute all of the following files. Once completed, withheld versions will be automatically published.`,
},
attentionNeededDescriptionDraft: {
id: 'project.settings.permissions.attention-needed.description.proj-draft',
- defaultMessage: `Please provide proof that you have permission to redistribute all of the following files before you can submit your project for review.`,
+ defaultMessage: `Please provide proof that you have permission to redistribute all of the following files before submitting your project for review.`,
},
noResults: {
id: 'project.settings.permissions.no-results',
- defaultMessage: 'No external projects match your search.',
+ defaultMessage: 'No external files match your search.',
},
})
diff --git a/packages/moderation/src/data/checklist.ts b/packages/moderation/src/data/checklist.ts
index 69cd061a54..8b8bb5d689 100644
--- a/packages/moderation/src/data/checklist.ts
+++ b/packages/moderation/src/data/checklist.ts
@@ -1,5 +1,4 @@
import type { Stage } from '../types/stage'
-import modpackPermissionsStage from './modpack-permissions-stage'
import categories from './stages/categories'
import description from './stages/description'
import environment from './stages/environment/environment'
@@ -7,6 +6,7 @@ import environmentMultiple from './stages/environment/environment-multiple'
import gallery from './stages/gallery'
import license from './stages/license'
import links from './stages/links'
+import permissions from './stages/permissions'
import postApproval from './stages/post-approval'
import reupload from './stages/reupload'
import ruleFollowing from './stages/rule-following'
@@ -28,8 +28,8 @@ export default [
gallery,
versions,
reupload,
+ permissions,
ruleFollowing,
- modpackPermissionsStage,
statusAlerts,
undefinedProject,
postApproval,
diff --git a/packages/moderation/src/data/messages/externals-permissions/invalid.md b/packages/moderation/src/data/messages/externals-permissions/invalid.md
new file mode 100644
index 0000000000..15e87e7623
--- /dev/null
+++ b/packages/moderation/src/data/messages/externals-permissions/invalid.md
@@ -0,0 +1,4 @@
+## Proof of Permissions
+
+You may not have the necessary rights or permissions to distribute some of the external content included in your Modpack.
+Per section 4 of %RULES%, we ask that you please complete all steps and address all notes left by moderators if any in your project's %PROJECT_PERMISSIONS_FLINK%.
diff --git a/packages/moderation/src/data/messages/externals-permissions/missing.md b/packages/moderation/src/data/messages/externals-permissions/missing.md
new file mode 100644
index 0000000000..9dc97b32b5
--- /dev/null
+++ b/packages/moderation/src/data/messages/externals-permissions/missing.md
@@ -0,0 +1,3 @@
+## Permissions Incomplete
+
+Per section 4 of %RULES%, we ask that you complete all steps requested in your project's %PROJECT_PERMISSIONS_FLINK%.
diff --git a/packages/moderation/src/data/messages/externals-permissions/prohibited.md b/packages/moderation/src/data/messages/externals-permissions/prohibited.md
new file mode 100644
index 0000000000..1d62230ff8
--- /dev/null
+++ b/packages/moderation/src/data/messages/externals-permissions/prohibited.md
@@ -0,0 +1,6 @@
+## Prohibited External Content
+
+Some external content in your mod was found to be prohibited.
+This means you cannot include these files in your Modpack on Modrinth, likely because it violates one of %RULES%.
+
+Please view your project's %PROJECT_PERMISSIONS_FLINK% for a list of what content must be removed from your pack before distribution on Modrinth.
diff --git a/packages/moderation/src/data/nags/core.ts b/packages/moderation/src/data/nags/core.ts
index 3085056eed..467f270f9c 100644
--- a/packages/moderation/src/data/nags/core.ts
+++ b/packages/moderation/src/data/nags/core.ts
@@ -194,4 +194,33 @@ export const coreNags: Nag[] = [
shouldShow: (context: NagContext) => context.currentRoute !== 'type-project-settings-license',
},
},
+ {
+ id: 'review-permissions',
+ title: defineMessage({
+ id: 'nags.review-permissions.title',
+ defaultMessage: 'Review external permissions',
+ }),
+ description: (context: NagContext) => {
+ const { formatMessage } = useVIntl()
+ return formatMessage(
+ defineMessage({
+ id: 'nags.review-permissions.description',
+ defaultMessage:
+ 'Make sure you have provided proof of your permission to distribute any external content in your Modpack.',
+ }),
+ )
+ },
+ status: 'required',
+ shouldShow: (context: NagContext) =>
+ context.versions.some((version) => (version.files_missing_attribution?.length ?? 0) >= 1),
+ link: {
+ path: 'settings/permissions',
+ title: defineMessage({
+ id: 'nags.settings.permissions.title',
+ defaultMessage: 'Visit permissions dashboard',
+ }),
+ shouldShow: (context: NagContext) =>
+ context.currentRoute !== 'type-project-settings-permissions',
+ },
+ },
]
diff --git a/packages/moderation/src/data/stages/permissions.ts b/packages/moderation/src/data/stages/permissions.ts
new file mode 100644
index 0000000000..a4a0d80d9a
--- /dev/null
+++ b/packages/moderation/src/data/stages/permissions.ts
@@ -0,0 +1,51 @@
+import { SignatureIcon } from '@modrinth/assets'
+
+import type { Stage } from '../../types/stage'
+
+const permissions: Stage = {
+ title: 'Does this projects external content have any issues?',
+ id: 'permissions',
+ icon: SignatureIcon,
+ guidance_url: 'https://www.notion.so/2e15ee711bf080e4a41df61bbab49892',
+ navigate: '/settings/permissions',
+ actions: [
+ {
+ id: 'invalid-permissions',
+ type: 'button',
+ label: 'Invalid permissions',
+ weight: 2000,
+ suggestedStatus: 'rejected',
+ severity: 'high',
+ shouldShow: (project, projectV3) =>
+ projectV3.project_types?.includes('modpack') && !projectV3?.minecraft_server,
+ message: async () =>
+ (await import('../messages/externals-permissions/invalid.md?raw')).default,
+ },
+ {
+ id: 'prohibited-extrernal-content',
+ type: 'button',
+ label: 'Prohibited externals',
+ weight: 2001,
+ suggestedStatus: 'rejected',
+ severity: 'high',
+ shouldShow: (project, projectV3) =>
+ projectV3.project_types?.includes('modpack') && !projectV3?.minecraft_server,
+ message: async () =>
+ (await import('../messages/externals-permissions/prohibited.md?raw')).default,
+ },
+ {
+ id: 'missing-permissions',
+ type: 'button',
+ label: 'Missing permissions',
+ weight: 2002,
+ suggestedStatus: 'rejected',
+ severity: 'high',
+ shouldShow: (project, projectV3) =>
+ projectV3.project_types?.includes('modpack') && !projectV3?.minecraft_server,
+ message: async () =>
+ (await import('../messages/externals-permissions/missing.md?raw')).default,
+ },
+ ],
+}
+
+export default permissions
diff --git a/packages/moderation/src/locales/en-US/index.json b/packages/moderation/src/locales/en-US/index.json
index 5cb10f1078..c34c88d4ac 100644
--- a/packages/moderation/src/locales/en-US/index.json
+++ b/packages/moderation/src/locales/en-US/index.json
@@ -140,6 +140,12 @@
"nags.multiple-resolution-tags.title": {
"defaultMessage": "Select correct resolution"
},
+ "nags.review-permissions.description": {
+ "defaultMessage": "Make sure you have provided proof of your permission to distribute any external content in your Modpack."
+ },
+ "nags.review-permissions.title": {
+ "defaultMessage": "Review external permissions"
+ },
"nags.select-compatibility.description": {
"defaultMessage": "Select what versions your server supports, choose a Modpack, or upload your own."
},
@@ -182,6 +188,9 @@
"nags.settings.links.title": {
"defaultMessage": "Visit links settings"
},
+ "nags.settings.permissions.title": {
+ "defaultMessage": "Visit permissions dashboard"
+ },
"nags.settings.tags.title": {
"defaultMessage": "Visit tag settings"
},
diff --git a/packages/moderation/src/types/nags.ts b/packages/moderation/src/types/nags.ts
index 3b5d49ee9b..c0a63cddd7 100644
--- a/packages/moderation/src/types/nags.ts
+++ b/packages/moderation/src/types/nags.ts
@@ -28,7 +28,7 @@ export interface NagContext {
/**
* The versions associated with the project.
*/
- versions: Labrinth.Versions.v2.Version[]
+ versions: Labrinth.Versions.v3.Version[]
/**
* The current project member viewing the nag.
*/
diff --git a/packages/moderation/src/utils.ts b/packages/moderation/src/utils.ts
index 0a076dd54a..970d0e446c 100644
--- a/packages/moderation/src/utils.ts
+++ b/packages/moderation/src/utils.ts
@@ -382,6 +382,10 @@ export function flattenProjectVariables(
vars[`PROJECT_LANGUAGE_SETTINGS`] = `https://modrinth.com/project/${project.id}/settings/server`
vars[`PROJECT_LANGUAGE_SETTINGS_FLINK`] =
`[Language Settings](https://modrinth.com/project/${project.id}/settings/server)`
+ vars[`PROJECT_PERMISSIONS_LINK`] =
+ `https://modrinth.com/project/${project.id}/settings/permissions`
+ vars[`PROJECT_PERMISSIONS_FLINK`] =
+ `[Permissions dashboard](https://modrinth.com/project/${project.id}/settings/permissions)`
return vars
}
diff --git a/packages/ui/src/components/external_files/ExternalProjectPermissionsCard.vue b/packages/ui/src/components/external_files/ExternalProjectPermissionsCard.vue
index 38eb319226..1783c9da7d 100644
--- a/packages/ui/src/components/external_files/ExternalProjectPermissionsCard.vue
+++ b/packages/ui/src/components/external_files/ExternalProjectPermissionsCard.vue
@@ -6,11 +6,11 @@ import {
EditIcon,
FileIcon,
PlusIcon,
+ ReportIcon,
ScaleIcon,
SpinnerIcon,
VersionIcon,
XCircleIcon,
- ReportIcon,
XIcon,
} from '@modrinth/assets'
import { useMutation, useQueryClient } from '@tanstack/vue-query'
@@ -25,6 +25,7 @@ import {
injectNotificationManager,
injectProjectPageContext,
} from '../../providers'
+import StyledInput from '../base/StyledInput.vue'
import AddFilesToAttributionGroupModal from './AddFilesToAttributionGroupModal.vue'
import AddToExistingExternalProjectModal from './AddToExistingExternalProjectModal.vue'
import AddToGlobalPermissionsDatabaseModal from './AddToGlobalPermissionsDatabaseModal.vue'
@@ -39,7 +40,6 @@ import {
parseInitialAttribution,
} from './external-project-utils'
import OriginalPageLink from './OriginalPageLink.vue'
-import StyledInput from '../base/StyledInput.vue'
const props = withDefaults(
defineProps<{
diff --git a/packages/ui/src/locales/en-US/index.json b/packages/ui/src/locales/en-US/index.json
index 0538a88f6a..6528d047ae 100644
--- a/packages/ui/src/locales/en-US/index.json
+++ b/packages/ui/src/locales/en-US/index.json
@@ -917,6 +917,18 @@
"external-files.permissions-card.link-to-work-url-placeholder": {
"defaultMessage": "link-to-work"
},
+ "external-files.permissions-card.moderation.approved": {
+ "defaultMessage": "Seems legit"
+ },
+ "external-files.permissions-card.moderation.bad-proof": {
+ "defaultMessage": "Insufficient proof"
+ },
+ "external-files.permissions-card.moderation.error.title": {
+ "defaultMessage": "Could not save moderation review"
+ },
+ "external-files.permissions-card.moderation.not-allowed": {
+ "defaultMessage": "Breaks rules"
+ },
"external-files.permissions-card.not-used-in-versions": {
"defaultMessage": "These files are not currently used by any version."
},
@@ -989,6 +1001,9 @@
"external-files.permissions-card.reason.special-permission.description": {
"defaultMessage": "You have obtained special permission to redistribute this work in your modpack."
},
+ "external-files.permissions-card.review-explanation-placeholder": {
+ "defaultMessage": "Explanation of review"
+ },
"external-files.permissions-card.save": {
"defaultMessage": "Save attribution"
},
@@ -1004,21 +1019,6 @@
"external-files.permissions-card.type-label": {
"defaultMessage": "Permission reason"
},
- "external-files.permissions-card.moderation.approved": {
- "defaultMessage": "Seems legit"
- },
- "external-files.permissions-card.moderation.bad-proof": {
- "defaultMessage": "Insufficient proof"
- },
- "external-files.permissions-card.moderation.error.title": {
- "defaultMessage": "Could not save moderation review"
- },
- "external-files.permissions-card.moderation.not-allowed": {
- "defaultMessage": "Breaks rules"
- },
- "external-files.permissions-card.review-explanation-placeholder": {
- "defaultMessage": "Explanation of review"
- },
"external-files.permissions-card.unnamed-multi-group-title": {
"defaultMessage": "{filename} + {count} more"
},