|
{env.APP_NAME}
-
+
Twitter
|
diff --git a/server/models/Collection.ts b/server/models/Collection.ts
index a2ae45716..925672139 100644
--- a/server/models/Collection.ts
+++ b/server/models/Collection.ts
@@ -34,9 +34,9 @@ import {
import isUUID from "validator/lib/isUUID";
import type { CollectionSort } from "@shared/types";
import { CollectionPermission, NavigationNode } from "@shared/types";
+import { UrlHelper } from "@shared/utils/UrlHelper";
import { sortNavigationNodes } from "@shared/utils/collections";
import slugify from "@shared/utils/slugify";
-import { SLUG_URL_REGEX } from "@shared/utils/urlHelpers";
import { CollectionValidation } from "@shared/validations";
import { ValidationError } from "@server/errors";
import Document from "./Document";
@@ -394,7 +394,7 @@ class Collection extends ParanoidModel<
});
}
- const match = id.match(SLUG_URL_REGEX);
+ const match = id.match(UrlHelper.SLUG_URL_REGEX);
if (match) {
return this.findOne({
where: {
diff --git a/server/models/Document.ts b/server/models/Document.ts
index ef13aa0a6..ca817a253 100644
--- a/server/models/Document.ts
+++ b/server/models/Document.ts
@@ -47,9 +47,9 @@ import type {
ProsemirrorData,
SourceMetadata,
} from "@shared/types";
+import { UrlHelper } from "@shared/utils/UrlHelper";
import getTasks from "@shared/utils/getTasks";
import slugify from "@shared/utils/slugify";
-import { SLUG_URL_REGEX } from "@shared/utils/urlHelpers";
import { DocumentValidation } from "@shared/validations";
import { ValidationError } from "@server/errors";
import Backlink from "./Backlink";
@@ -611,7 +611,7 @@ class Document extends ParanoidModel<
return document;
}
- const match = id.match(SLUG_URL_REGEX);
+ const match = id.match(UrlHelper.SLUG_URL_REGEX);
if (match) {
const document = await scope.findOne({
where: {
diff --git a/server/models/Share.ts b/server/models/Share.ts
index 2657756c5..ee2191dad 100644
--- a/server/models/Share.ts
+++ b/server/models/Share.ts
@@ -17,7 +17,7 @@ import {
Unique,
BeforeUpdate,
} from "sequelize-typescript";
-import { SHARE_URL_SLUG_REGEX } from "@shared/utils/urlHelpers";
+import { UrlHelper } from "@shared/utils/UrlHelper";
import env from "@server/env";
import { ValidationError } from "@server/errors";
import Collection from "./Collection";
@@ -96,7 +96,7 @@ class Share extends IdModel<
@AllowNull
@Is({
- args: SHARE_URL_SLUG_REGEX,
+ args: UrlHelper.SHARE_URL_SLUG_REGEX,
msg: "Must be only alphanumeric and dashes",
})
@Column
diff --git a/server/routes/api/documents/schema.ts b/server/routes/api/documents/schema.ts
index a7aac22aa..e3c05991f 100644
--- a/server/routes/api/documents/schema.ts
+++ b/server/routes/api/documents/schema.ts
@@ -4,7 +4,7 @@ import isEmpty from "lodash/isEmpty";
import isUUID from "validator/lib/isUUID";
import { z } from "zod";
import { DocumentPermission, StatusFilter } from "@shared/types";
-import { SHARE_URL_SLUG_REGEX } from "@shared/utils/urlHelpers";
+import { UrlHelper } from "@shared/utils/UrlHelper";
import { BaseSchema } from "@server/routes/api/schema";
const DocumentsSortParamsSchema = z.object({
@@ -115,7 +115,7 @@ export const DocumentsInfoSchema = BaseSchema.extend({
/** Share Id, if available */
shareId: z
.string()
- .refine((val) => isUUID(val) || SHARE_URL_SLUG_REGEX.test(val))
+ .refine((val) => isUUID(val) || UrlHelper.SHARE_URL_SLUG_REGEX.test(val))
.optional(),
/** Version of the API to be used */
@@ -173,7 +173,7 @@ export const DocumentsSearchSchema = BaseSchema.extend({
/** Filter results for the team derived from shareId */
shareId: z
.string()
- .refine((val) => isUUID(val) || SHARE_URL_SLUG_REGEX.test(val))
+ .refine((val) => isUUID(val) || UrlHelper.SHARE_URL_SLUG_REGEX.test(val))
.optional(),
/** Min words to be shown in the results snippets */
diff --git a/server/routes/api/pins/schema.ts b/server/routes/api/pins/schema.ts
index d3592a80f..e659e72a4 100644
--- a/server/routes/api/pins/schema.ts
+++ b/server/routes/api/pins/schema.ts
@@ -1,6 +1,6 @@
import isUUID from "validator/lib/isUUID";
import { z } from "zod";
-import { SLUG_URL_REGEX } from "@shared/utils/urlHelpers";
+import { UrlHelper } from "@shared/utils/UrlHelper";
import { BaseSchema } from "../schema";
export const PinsCreateSchema = BaseSchema.extend({
@@ -9,7 +9,7 @@ export const PinsCreateSchema = BaseSchema.extend({
.string({
required_error: "required",
})
- .refine((val) => isUUID(val) || SLUG_URL_REGEX.test(val), {
+ .refine((val) => isUUID(val) || UrlHelper.SLUG_URL_REGEX.test(val), {
message: "must be uuid or url slug",
}),
collectionId: z.string().uuid().nullish(),
diff --git a/server/routes/api/shares/schema.ts b/server/routes/api/shares/schema.ts
index 8ff0210fc..6a263f5ed 100644
--- a/server/routes/api/shares/schema.ts
+++ b/server/routes/api/shares/schema.ts
@@ -1,7 +1,7 @@
import isEmpty from "lodash/isEmpty";
import isUUID from "validator/lib/isUUID";
import { z } from "zod";
-import { SHARE_URL_SLUG_REGEX, SLUG_URL_REGEX } from "@shared/utils/urlHelpers";
+import { UrlHelper } from "@shared/utils/UrlHelper";
import { Share } from "@server/models";
import { BaseSchema } from "../schema";
@@ -13,7 +13,8 @@ export const SharesInfoSchema = BaseSchema.extend({
.string()
.optional()
.refine(
- (val) => (val ? isUUID(val) || SLUG_URL_REGEX.test(val) : true),
+ (val) =>
+ val ? isUUID(val) || UrlHelper.SLUG_URL_REGEX.test(val) : true,
{
message: "must be uuid or url slug",
}
@@ -52,7 +53,7 @@ export const SharesUpdateSchema = BaseSchema.extend({
published: z.boolean().optional(),
urlId: z
.string()
- .regex(SHARE_URL_SLUG_REGEX, {
+ .regex(UrlHelper.SHARE_URL_SLUG_REGEX, {
message: "must contain only alphanumeric and dashes",
})
.nullish(),
@@ -65,13 +66,13 @@ export const SharesCreateSchema = BaseSchema.extend({
body: z.object({
documentId: z
.string()
- .refine((val) => isUUID(val) || SLUG_URL_REGEX.test(val), {
+ .refine((val) => isUUID(val) || UrlHelper.SLUG_URL_REGEX.test(val), {
message: "must be uuid or url slug",
}),
published: z.boolean().default(false),
urlId: z
.string()
- .regex(SHARE_URL_SLUG_REGEX, {
+ .regex(UrlHelper.SHARE_URL_SLUG_REGEX, {
message: "must contain only alphanumeric and dashes",
})
.optional(),
diff --git a/server/validation.ts b/server/validation.ts
index 097bf1281..eff13375c 100644
--- a/server/validation.ts
+++ b/server/validation.ts
@@ -5,10 +5,10 @@ import validator from "validator";
import isIn from "validator/lib/isIn";
import isUUID from "validator/lib/isUUID";
import { CollectionPermission } from "@shared/types";
+import { UrlHelper } from "@shared/utils/UrlHelper";
import { validateColorHex } from "@shared/utils/color";
import { validateIndexCharacters } from "@shared/utils/indexCharacters";
import parseMentionUrl from "@shared/utils/parseMentionUrl";
-import { SLUG_URL_REGEX } from "@shared/utils/urlHelpers";
import { isUrl } from "@shared/utils/urls";
import { ParamRequiredError, ValidationError } from "./errors";
import { Buckets } from "./models/helpers/AttachmentHelper";
@@ -210,7 +210,7 @@ export class ValidateDocumentId {
* @returns true if documentId is valid, false otherwise
*/
public static isValid = (documentId: string) =>
- isUUID(documentId) || SLUG_URL_REGEX.test(documentId);
+ isUUID(documentId) || UrlHelper.SLUG_URL_REGEX.test(documentId);
public static message = "Must be uuid or url slug";
}
diff --git a/shared/utils/UrlHelper.ts b/shared/utils/UrlHelper.ts
new file mode 100644
index 000000000..69d3cc04d
--- /dev/null
+++ b/shared/utils/UrlHelper.ts
@@ -0,0 +1,10 @@
+export class UrlHelper {
+ public static github = "https://www.github.com/outline/outline/issues";
+ public static twitter = "https://twitter.com/getoutline";
+ public static contact = "https://www.getoutline.com/contact";
+ public static developers = "https://www.getoutline.com/developers";
+ public static changelog = "https://www.getoutline.com/changelog";
+
+ public static SLUG_URL_REGEX = /^(?:[0-9a-zA-Z-_~]*-)?([a-zA-Z0-9]{10,15})$/;
+ public static SHARE_URL_SLUG_REGEX = /^[0-9a-z-]+$/;
+}
diff --git a/shared/utils/urlHelpers.ts b/shared/utils/urlHelpers.ts
deleted file mode 100644
index 5d97822fe..000000000
--- a/shared/utils/urlHelpers.ts
+++ /dev/null
@@ -1,53 +0,0 @@
-import env from "../env";
-
-export function slackAuth(
- state: string,
- scopes: string[] = [
- "identity.email",
- "identity.basic",
- "identity.avatar",
- "identity.team",
- ],
- clientId: string,
- redirectUri = `${env.URL}/auth/slack.callback`
-): string {
- const baseUrl = "https://slack.com/oauth/authorize";
- const params = {
- client_id: clientId,
- scope: scopes ? scopes.join(" ") : "",
- redirect_uri: redirectUri,
- state,
- };
- const urlParams = Object.keys(params)
- .map((key) => `${key}=${encodeURIComponent(params[key])}`)
- .join("&");
- return `${baseUrl}?${urlParams}`;
-}
-
-export function githubUrl(): string {
- return "https://www.github.com/outline";
-}
-
-export function githubIssuesUrl(): string {
- return "https://www.github.com/outline/outline/issues";
-}
-
-export function twitterUrl(): string {
- return "https://twitter.com/getoutline";
-}
-
-export function feedbackUrl(): string {
- return "https://www.getoutline.com/contact";
-}
-
-export function developersUrl(): string {
- return "https://www.getoutline.com/developers";
-}
-
-export function changelogUrl(): string {
- return "https://www.getoutline.com/changelog";
-}
-
-export const SLUG_URL_REGEX = /^(?:[0-9a-zA-Z-_~]*-)?([a-zA-Z0-9]{10,15})$/;
-
-export const SHARE_URL_SLUG_REGEX = /^[0-9a-z-]+$/;