diff --git a/app/[locale]/Header.tsx b/app/[locale]/Header.tsx
index cca4a8ec..87c19387 100644
--- a/app/[locale]/Header.tsx
+++ b/app/[locale]/Header.tsx
@@ -25,14 +25,13 @@ export default function Header() {
about: {
about: tNav("about.about"),
charter: tNav("about.charter"),
+ wiki: tNav("about.wiki"),
partners: tNav("about.partners"),
sponsors: tNav("about.sponsors"),
},
resources: {
- faq: tNav("resources.faq"),
- guidesAndManuals: tNav("resources.guidesAndManuals"),
+ docs: tNav("resources.docs"),
gpgKeyInfo: tNav("resources.gpgKeyInfo"),
- wiki: tNav("resources.wiki"),
},
community: {
forums: tNav("community.forums"),
diff --git a/app/[locale]/components/header/DesktopNavigation.tsx b/app/[locale]/components/header/DesktopNavigation.tsx
index aba0aa2d..38994df6 100644
--- a/app/[locale]/components/header/DesktopNavigation.tsx
+++ b/app/[locale]/components/header/DesktopNavigation.tsx
@@ -32,6 +32,10 @@ const DesktopNavigation = ({ translations: t }: DesktopNavigationProps) => {
title={t.about.charter}
href="/about/charter"
/>
+
{
-
-
@@ -88,13 +84,13 @@ const DesktopNavigation = ({ translations: t }: DesktopNavigationProps) => {
/>
{
/>
diff --git a/app/[locale]/components/header/MobileNavigation.tsx b/app/[locale]/components/header/MobileNavigation.tsx
index 963bf9d7..aa671ab4 100644
--- a/app/[locale]/components/header/MobileNavigation.tsx
+++ b/app/[locale]/components/header/MobileNavigation.tsx
@@ -71,6 +71,10 @@ const MobileNavigation = ({
title={t.about.charter}
href="/about/charter"
/>
+
-
-
@@ -127,13 +123,13 @@ const MobileNavigation = ({
/>
diff --git a/app/[locale]/components/header/NavigationTypes.ts b/app/[locale]/components/header/NavigationTypes.ts
index 333c4c0f..3912f7a2 100644
--- a/app/[locale]/components/header/NavigationTypes.ts
+++ b/app/[locale]/components/header/NavigationTypes.ts
@@ -8,13 +8,12 @@ export interface NavigationMenuItems {
about: {
about: string;
charter: string;
+ wiki: string;
sponsors: string;
partners: string;
};
resources: {
- faq: string;
- wiki: string;
- guidesAndManuals: string;
+ docs: string;
gpgKeyInfo: string;
};
community: {
diff --git a/app/[locale]/resources/[slug]/not-found.tsx b/app/[locale]/resources/[slug]/not-found.tsx
new file mode 100644
index 00000000..97bbda40
--- /dev/null
+++ b/app/[locale]/resources/[slug]/not-found.tsx
@@ -0,0 +1,18 @@
+import { useTranslations } from "next-intl";
+
+export default function SlugNotFound() {
+ const t = useTranslations("global.notFound");
+
+ return (
+
+
+
+ {t("title")}
+
+
+ {t("description")}
+
+
+
+ );
+}
diff --git a/app/[locale]/resources/[slug]/page.tsx b/app/[locale]/resources/[slug]/page.tsx
new file mode 100644
index 00000000..52bab582
--- /dev/null
+++ b/app/[locale]/resources/[slug]/page.tsx
@@ -0,0 +1,56 @@
+import { checkIfSlugIsValid, getContentData } from "@/lib/resourcesPages";
+import { notFound } from "next/navigation";
+
+export type Params = {
+ slug: string;
+};
+
+export type Props = {
+ params: Params;
+};
+
+export type pageData = {
+ title: string;
+ description: string;
+ contentHtml: string;
+};
+
+export async function generateMetadata({ params }: Props) {
+ const slug = params.slug;
+
+ if (!(await checkIfSlugIsValid(slug))) {
+ return {
+ title: "Not Found",
+ };
+ }
+
+ const pageData: pageData = await getContentData(slug);
+
+ return {
+ title: `${pageData.title} - Rocky Linux`,
+ };
+}
+
+export default async function Page({ params }: Props) {
+ const slug = params.slug;
+
+ if (!(await checkIfSlugIsValid(slug))) {
+ notFound();
+ }
+
+ const pageData: pageData = await getContentData(slug);
+
+ return (
+
+
+
+ {pageData.title}
+
+
+
+
+ );
+}
diff --git a/lib/resourcesPages.ts b/lib/resourcesPages.ts
new file mode 100644
index 00000000..9e354c57
--- /dev/null
+++ b/lib/resourcesPages.ts
@@ -0,0 +1,47 @@
+import fs from "fs";
+import path from "path";
+
+import matter from "gray-matter";
+import { processMarkdownAsHTML } from "@/utils/remarkUtils";
+
+const contentDirectory = path.join(process.cwd(), "resources");
+
+export async function checkIfSlugIsValid(slug: string) {
+ if (!slug || typeof slug !== "string") {
+ return false;
+ }
+
+ // Check that the slug does not contain any slashes to prevent directory traversal
+ if (slug.includes("/") || slug.includes("\\")) {
+ return false;
+ }
+
+ const fullPath = path.join(contentDirectory, `${slug}.md`);
+
+ try {
+ await fs.promises.access(fullPath);
+ return true;
+ } catch {
+ return false;
+ }
+}
+
+export async function getContentData(slug: string) {
+ const fullPath = path.join(contentDirectory, `${slug}.md`);
+
+ const fileContents = await fs.promises.readFile(fullPath, "utf8");
+
+ if (!fileContents) {
+ throw new Error(`Page with slug "${slug}" does not exist.`);
+ }
+
+ const matterResult = matter(fileContents);
+
+ const contentHtml = await processMarkdownAsHTML(matterResult.content);
+
+ return {
+ slug,
+ contentHtml,
+ ...(matterResult.data as { title: string; description: string }),
+ };
+}
diff --git a/messages/en.json b/messages/en.json
index 42a1db6d..5ce3f474 100644
--- a/messages/en.json
+++ b/messages/en.json
@@ -20,13 +20,12 @@
"about": {
"about": "About Rocky Linux",
"charter": "Community Charter",
+ "wiki": "Project Wiki",
"sponsors": "Sponsors",
"partners": "Partners"
},
"resources": {
- "faq": "Frequently Asked Questions",
- "wiki": "Wiki",
- "guidesAndManuals": "Guides & Manuals",
+ "docs": "Documentation",
"gpgKeyInfo": "GPG Key Info"
},
"community": {
@@ -41,7 +40,7 @@
"submitBug": "Submit Bug"
},
"contribute": {
- "contribute": "Contribute",
+ "contribute": "Contributing Guide",
"shop": "Shop",
"donate": "Donate"
}
diff --git a/resources/gpg-key-info.md b/resources/gpg-key-info.md
new file mode 100644
index 00000000..a744b47a
--- /dev/null
+++ b/resources/gpg-key-info.md
@@ -0,0 +1,84 @@
+---
+title: GPG Key Info
+description: "This document contains information on how we use GPG keys."
+---
+
+## How Rocky Linux uses GPG keys
+
+Each stable RPM package that is published by Rocky Linux is signed with a GPG signature. By default, `yum` and the graphical update tools will verify these signatures and refuse to install any packages that are not signed, or have an incorrect signature. You should always verify the signature of the package prior to installation. These signatures ensure that the packages you install are what was produced by Rocky Linux and have not been altered by any mirror or website providing the packages.
+
+---
+
+## Importing Keys
+
+The Project GPG keys are included in the `rockylinux-release` package, and are typically found in `/etc/pki/rpm-gpg`. Please note that not all keys in this directory are used by the Rocky Linux project. Some keys may be placed in this directory by 3rd party repositories to enable the secure use of extra packages, as well. The keys used by Rocky Linux are enabled in the `yum` repository configuration, so you generally don't need to manually import them.
+
+If you want to verify that the keys installed on your system match the keys listed here, you can use GnuPG to check that the key fingerprint matches. For example:
+
+```
+gpg --quiet --show-keys /etc/pki/rpm-gpg/RPM-GPG-KEY-rockyofficial
+pub rsa4096 2021-02-14 [SCE]
+ 7051C470A929F454CEBE37B715AF5DAC6D745A60
+uid Release Engineering
+```
+
+---
+
+## Project Keys
+
+The following keys are currently in use by Rocky Linux. Please note that Rocky Linux releases may have several GPG keys assigned (depending on the release and architecture).
+
+### Rocky Linux Release Keys
+
+#### Rocky Linux 8
+
+[Download Key](https://dl.rockylinux.org/pub/rocky/RPM-GPG-KEY-Rocky-8)
+
+```
+pub rsa4096/0x15AF5DAC6D745A60 2021-02-14 Rocky Linux (Rocky Linux Official Signing Key)
+Key Fingerprint = 7051 C470 A929 F454 CEBE 37B7 15AF 5DAC 6D74 5A60
+```
+
+#### Rocky Linux 9
+
+[Download Key](https://dl.rockylinux.org/pub/rocky/RPM-GPG-KEY-Rocky-9)
+
+```
+pub rsa4096/0x702D426D350D275D 2022-05-09 Rocky Enterprise Software Foundation - Release key 2022
+Key Fingerprint = 21CB 256A E16F C54C 6E65 2949 702D 426D 350D 275D
+```
+
+### Rocky Linux Testing Keys
+
+#### Rocky Linux 8
+
+[Download Key](https://dl.rockylinux.org/pub/rocky/RPM-GPG-KEY-Rocky-8-Testing)
+
+```
+pub rsa4096/0x5489E42BBBE2C108 2021-02-14 Rocky Linux Testing (Rocky Linux Testing Key)
+Key fingerprint = 091A 4404 7C3D 8B7A 331F 5E18 5489 E42B BBE2 C108
+```
+
+#### Rocky Linux 9
+
+[Download Key](https://dl.rockylinux.org/pub/rocky/RPM-GPG-KEY-Rocky-9-Testing)
+
+```
+pub rsa4096/0xADA2860895AE3D91 2022-04-26 Rocky Linux 9 - Beta Key V1/2022
+Key fingerprint = 0675 BD19 F4FF E3AD 0B2D 6FEB ADA2 8608 95AE 3D91
+```
+
+### Rocky Linux Infrastructure Keys
+
+#### Rocky Linux 8
+
+[Download Key](https://dl.rockylinux.org/pub/rocky/RPM-GPG-KEY-rockyinfra)
+
+```
+sec ed25519/0xAA650F52D6C094FA 2021-05-17 Core Infrastructure (Compose Signing Key)
+Key fingerprint = BFC3 D8F2 0D15 F4FD 4628 1D7F AA65 0F52 D6C0 94FA
+```
+
+#### Rocky Linux 9
+
+Not applicable.