mirror of
https://github.com/outline/outline.git
synced 2025-12-30 15:30:12 -06:00
fix: replace uuid package with standard module (#10318)
This commit is contained in:
@@ -2,7 +2,6 @@ import { LocationDescriptor } from "history";
|
||||
import flattenDeep from "lodash/flattenDeep";
|
||||
import { toast } from "sonner";
|
||||
import { Optional } from "utility-types";
|
||||
import { v4 as uuidv4 } from "uuid";
|
||||
import {
|
||||
Action,
|
||||
ActionContext,
|
||||
@@ -46,7 +45,7 @@ export function createAction(definition: Optional<Action, "id">): Action {
|
||||
return definition.perform?.(context);
|
||||
}
|
||||
: undefined,
|
||||
id: definition.id ?? uuidv4(),
|
||||
id: definition.id ?? crypto.randomUUID(),
|
||||
};
|
||||
}
|
||||
|
||||
@@ -202,7 +201,7 @@ export function createActionV2(
|
||||
return definition.perform(context);
|
||||
}
|
||||
: () => {},
|
||||
id: definition.id ?? uuidv4(),
|
||||
id: definition.id ?? crypto.randomUUID(),
|
||||
};
|
||||
}
|
||||
|
||||
@@ -213,7 +212,7 @@ export function createInternalLinkActionV2(
|
||||
...definition,
|
||||
type: "action",
|
||||
variant: "internal_link",
|
||||
id: definition.id ?? uuidv4(),
|
||||
id: definition.id ?? crypto.randomUUID(),
|
||||
};
|
||||
}
|
||||
|
||||
@@ -224,7 +223,7 @@ export function createExternalLinkActionV2(
|
||||
...definition,
|
||||
type: "action",
|
||||
variant: "external_link",
|
||||
id: definition.id ?? uuidv4(),
|
||||
id: definition.id ?? crypto.randomUUID(),
|
||||
};
|
||||
}
|
||||
|
||||
@@ -235,7 +234,7 @@ export function createActionV2WithChildren(
|
||||
...definition,
|
||||
type: "action",
|
||||
variant: "action_with_children",
|
||||
id: definition.id ?? uuidv4(),
|
||||
id: definition.id ?? crypto.randomUUID(),
|
||||
};
|
||||
}
|
||||
|
||||
@@ -252,7 +251,7 @@ export function createRootMenuAction(
|
||||
actions: (ActionV2Variant | ActionV2Group | TActionV2Separator)[]
|
||||
): ActionV2WithChildren {
|
||||
return {
|
||||
id: uuidv4(),
|
||||
id: crypto.randomUUID(),
|
||||
type: "action",
|
||||
variant: "action_with_children",
|
||||
name: "root_action",
|
||||
|
||||
@@ -5,7 +5,6 @@ import { useState, useCallback, useEffect } from "react";
|
||||
import { useTranslation } from "react-i18next";
|
||||
import { useLocation } from "react-router-dom";
|
||||
import { toast } from "sonner";
|
||||
import { v4 } from "uuid";
|
||||
import Icon from "@shared/components/Icon";
|
||||
import { MenuItem } from "@shared/editor/types";
|
||||
import { MentionType } from "@shared/types";
|
||||
@@ -92,7 +91,7 @@ function MentionMenu({ search, isActive, ...rest }: Props) {
|
||||
section: UserSection,
|
||||
appendSpace: true,
|
||||
attrs: {
|
||||
id: v4(),
|
||||
id: crypto.randomUUID(),
|
||||
type: MentionType.User,
|
||||
modelId: user.id,
|
||||
actorId,
|
||||
@@ -124,7 +123,7 @@ function MentionMenu({ search, isActive, ...rest }: Props) {
|
||||
section: DocumentsSection,
|
||||
appendSpace: true,
|
||||
attrs: {
|
||||
id: v4(),
|
||||
id: crypto.randomUUID(),
|
||||
type: MentionType.Document,
|
||||
modelId: doc.id,
|
||||
actorId,
|
||||
@@ -152,7 +151,7 @@ function MentionMenu({ search, isActive, ...rest }: Props) {
|
||||
section: CollectionsSection,
|
||||
appendSpace: true,
|
||||
attrs: {
|
||||
id: v4(),
|
||||
id: crypto.randomUUID(),
|
||||
type: MentionType.Collection,
|
||||
modelId: collection.id,
|
||||
actorId,
|
||||
@@ -172,9 +171,9 @@ function MentionMenu({ search, isActive, ...rest }: Props) {
|
||||
priority: -1,
|
||||
appendSpace: true,
|
||||
attrs: {
|
||||
id: v4(),
|
||||
id: crypto.randomUUID(),
|
||||
type: MentionType.Document,
|
||||
modelId: v4(),
|
||||
modelId: crypto.randomUUID(),
|
||||
actorId,
|
||||
label: search,
|
||||
},
|
||||
|
||||
@@ -2,7 +2,6 @@ import { observer } from "mobx-react";
|
||||
import { EmailIcon, LinkIcon } from "outline-icons";
|
||||
import React from "react";
|
||||
import { useTranslation } from "react-i18next";
|
||||
import { v4 } from "uuid";
|
||||
import { EmbedDescriptor } from "@shared/editor/embeds";
|
||||
import { MenuItem } from "@shared/editor/types";
|
||||
import { MentionType } from "@shared/types";
|
||||
@@ -97,11 +96,11 @@ function useItems({
|
||||
icon: <EmailIcon />,
|
||||
visible: !!mentionType,
|
||||
attrs: {
|
||||
id: v4(),
|
||||
id: crypto.randomUUID(),
|
||||
type: mentionType,
|
||||
label: pastedText,
|
||||
href: pastedText,
|
||||
modelId: v4(),
|
||||
modelId: crypto.randomUUID(),
|
||||
actorId: user?.id,
|
||||
},
|
||||
appendSpace: true,
|
||||
|
||||
@@ -8,7 +8,6 @@ import {
|
||||
TextSelection,
|
||||
} from "prosemirror-state";
|
||||
import { Decoration, DecorationSet } from "prosemirror-view";
|
||||
import { v4 } from "uuid";
|
||||
import Extension, { WidgetProps } from "@shared/editor/lib/Extension";
|
||||
import { codeLanguages } from "@shared/editor/lib/code";
|
||||
import isMarkdown from "@shared/editor/lib/isMarkdown";
|
||||
@@ -144,7 +143,7 @@ export default class PasteHandler extends Extension {
|
||||
type: MentionType.Document,
|
||||
modelId: document.id,
|
||||
label: document.titleWithDefault,
|
||||
id: v4(),
|
||||
id: crypto.randomUUID(),
|
||||
})
|
||||
)
|
||||
);
|
||||
@@ -189,7 +188,7 @@ export default class PasteHandler extends Extension {
|
||||
type: MentionType.Collection,
|
||||
modelId: collection.id,
|
||||
label: collection.name,
|
||||
id: v4(),
|
||||
id: crypto.randomUUID(),
|
||||
})
|
||||
)
|
||||
);
|
||||
|
||||
@@ -7,7 +7,6 @@ import * as React from "react";
|
||||
import { useTranslation } from "react-i18next";
|
||||
import { toast } from "sonner";
|
||||
import { useTheme } from "styled-components";
|
||||
import { v4 as uuidv4 } from "uuid";
|
||||
import { ProsemirrorData } from "@shared/types";
|
||||
import { getEventFiles } from "@shared/utils/files";
|
||||
import { AttachmentValidation, CommentValidation } from "@shared/validations";
|
||||
@@ -156,7 +155,7 @@ function CommentForm({
|
||||
comments
|
||||
);
|
||||
|
||||
comment.id = uuidv4();
|
||||
comment.id = crypto.randomUUID();
|
||||
comments.add(comment);
|
||||
|
||||
comment
|
||||
|
||||
@@ -6,7 +6,6 @@ import { useHistory, useLocation, useRouteMatch } from "react-router-dom";
|
||||
import { Waypoint } from "react-waypoint";
|
||||
import styled from "styled-components";
|
||||
import breakpoint from "styled-components-breakpoint";
|
||||
import { v4 as uuidv4 } from "uuid";
|
||||
import { Pagination } from "@shared/constants";
|
||||
import { hideScrollbars } from "@shared/styles";
|
||||
import {
|
||||
@@ -105,7 +104,7 @@ function Search() {
|
||||
// without a flash of loading.
|
||||
if (query) {
|
||||
searches.add({
|
||||
id: uuidv4(),
|
||||
id: crypto.randomUUID(),
|
||||
query,
|
||||
createdAt: new Date().toISOString(),
|
||||
});
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
import { observable, action } from "mobx";
|
||||
import * as React from "react";
|
||||
import { v4 as uuidv4 } from "uuid";
|
||||
|
||||
type DialogDefinition = {
|
||||
title: string;
|
||||
@@ -66,7 +65,7 @@ export default class DialogsStore {
|
||||
this.modalStack.clear();
|
||||
}
|
||||
|
||||
this.modalStack.set(id ?? replaceId ?? uuidv4(), {
|
||||
this.modalStack.set(id ?? replaceId ?? crypto.randomUUID(), {
|
||||
title,
|
||||
content,
|
||||
style,
|
||||
|
||||
@@ -262,7 +262,6 @@
|
||||
"ukkonen": "^2.2.0",
|
||||
"umzug": "^3.8.2",
|
||||
"utility-types": "^3.11.0",
|
||||
"uuid": "^8.3.2",
|
||||
"validator": "13.15.15",
|
||||
"vaul": "^1.1.2",
|
||||
"vite": "npm:rolldown-vite@latest",
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import { faker } from "@faker-js/faker";
|
||||
import { v4 as uuidv4 } from "uuid";
|
||||
import { randomUUID } from "crypto";
|
||||
import WelcomeEmail from "@server/emails/templates/WelcomeEmail";
|
||||
import { TeamDomain } from "@server/models";
|
||||
import Collection from "@server/models/Collection";
|
||||
@@ -35,7 +35,7 @@ describe("accountProvisioner", () => {
|
||||
providerId: faker.internet.domainName(),
|
||||
},
|
||||
authentication: {
|
||||
providerId: uuidv4(),
|
||||
providerId: randomUUID(),
|
||||
accessToken: "123",
|
||||
scopes: ["read"],
|
||||
},
|
||||
@@ -137,7 +137,7 @@ describe("accountProvisioner", () => {
|
||||
providerId: authenticationProvider.providerId,
|
||||
},
|
||||
authentication: {
|
||||
providerId: uuidv4(),
|
||||
providerId: randomUUID(),
|
||||
accessToken: "123",
|
||||
scopes: ["read"],
|
||||
},
|
||||
@@ -271,7 +271,7 @@ describe("accountProvisioner", () => {
|
||||
providerId: authenticationProvider.providerId,
|
||||
},
|
||||
authentication: {
|
||||
providerId: uuidv4(),
|
||||
providerId: randomUUID(),
|
||||
accessToken: "123",
|
||||
scopes: ["read"],
|
||||
},
|
||||
@@ -313,7 +313,7 @@ describe("accountProvisioner", () => {
|
||||
providerId: authenticationProvider.providerId,
|
||||
},
|
||||
authentication: {
|
||||
providerId: uuidv4(),
|
||||
providerId: randomUUID(),
|
||||
accessToken: "123",
|
||||
scopes: ["read"],
|
||||
},
|
||||
@@ -361,7 +361,7 @@ describe("accountProvisioner", () => {
|
||||
providerId: authenticationProvider.providerId,
|
||||
},
|
||||
authentication: {
|
||||
providerId: uuidv4(),
|
||||
providerId: randomUUID(),
|
||||
accessToken: "123",
|
||||
scopes: ["read"],
|
||||
},
|
||||
@@ -405,7 +405,7 @@ describe("accountProvisioner", () => {
|
||||
providerId: faker.internet.domainName(),
|
||||
},
|
||||
authentication: {
|
||||
providerId: uuidv4(),
|
||||
providerId: randomUUID(),
|
||||
accessToken: "123",
|
||||
scopes: ["read"],
|
||||
},
|
||||
@@ -458,7 +458,7 @@ describe("accountProvisioner", () => {
|
||||
providerId: faker.internet.domainName(),
|
||||
},
|
||||
authentication: {
|
||||
providerId: uuidv4(),
|
||||
providerId: randomUUID(),
|
||||
accessToken: "123",
|
||||
scopes: ["read"],
|
||||
},
|
||||
@@ -491,7 +491,7 @@ describe("accountProvisioner", () => {
|
||||
providerId: domain,
|
||||
},
|
||||
authentication: {
|
||||
providerId: uuidv4(),
|
||||
providerId: randomUUID(),
|
||||
accessToken: "123",
|
||||
scopes: ["read"],
|
||||
},
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { v4 as uuidv4 } from "uuid";
|
||||
import { randomUUID } from "crypto";
|
||||
import { AttachmentPreset } from "@shared/types";
|
||||
import { Attachment, User } from "@server/models";
|
||||
import AttachmentHelper from "@server/models/helpers/AttachmentHelper";
|
||||
@@ -47,7 +47,7 @@ export default async function attachmentCreator({
|
||||
const acl = AttachmentHelper.presetToAcl(preset);
|
||||
const key = AttachmentHelper.getKey({
|
||||
acl,
|
||||
id: uuidv4(),
|
||||
id: randomUUID(),
|
||||
name,
|
||||
userId: user.id,
|
||||
});
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { v4 as uuidv4 } from "uuid";
|
||||
import { randomUUID } from "crypto";
|
||||
import {
|
||||
FileOperationFormat,
|
||||
FileOperationType,
|
||||
@@ -25,7 +25,7 @@ function getKeyForFileOp(
|
||||
) {
|
||||
return `${
|
||||
Buckets.uploads
|
||||
}/${teamId}/${uuidv4()}/${name}-export.${format.replace(/outline-/, "")}.zip`;
|
||||
}/${teamId}/${randomUUID()}/${name}-export.${format.replace(/outline-/, "")}.zip`;
|
||||
}
|
||||
|
||||
async function collectionExporter({
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import { faker } from "@faker-js/faker";
|
||||
import { v4 as uuidv4 } from "uuid";
|
||||
import { randomUUID } from "crypto";
|
||||
import { UserRole } from "@shared/types";
|
||||
import { TeamDomain } from "@server/models";
|
||||
import {
|
||||
@@ -60,7 +60,7 @@ describe("userProvisioner", () => {
|
||||
teamId: existing.teamId,
|
||||
authentication: {
|
||||
authenticationProviderId: authenticationProvider.id,
|
||||
providerId: uuidv4(),
|
||||
providerId: randomUUID(),
|
||||
accessToken: "123",
|
||||
scopes: ["read"],
|
||||
},
|
||||
@@ -94,7 +94,7 @@ describe("userProvisioner", () => {
|
||||
teamId: existing.teamId,
|
||||
authentication: {
|
||||
authenticationProviderId: authenticationProvider.id,
|
||||
providerId: uuidv4(),
|
||||
providerId: randomUUID(),
|
||||
accessToken: "123",
|
||||
scopes: ["read"],
|
||||
},
|
||||
@@ -148,7 +148,7 @@ describe("userProvisioner", () => {
|
||||
email: "test@example.com",
|
||||
teamId: existing.teamId,
|
||||
authentication: {
|
||||
authenticationProviderId: uuidv4(),
|
||||
authenticationProviderId: randomUUID(),
|
||||
providerId: existingAuth.providerId,
|
||||
accessToken: "123",
|
||||
scopes: ["read"],
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { v4 as uuidv4 } from "uuid";
|
||||
import { randomUUID } from "crypto";
|
||||
import { randomString } from "@shared/random";
|
||||
import slugify from "@shared/utils/slugify";
|
||||
import {
|
||||
@@ -101,7 +101,7 @@ describe("getDocumentTree", () => {
|
||||
describe("#addDocumentToStructure", () => {
|
||||
it("should add as last element without index", async () => {
|
||||
const collection = await buildCollection();
|
||||
const id = uuidv4();
|
||||
const id = randomUUID();
|
||||
const newDocument = await buildDocument({
|
||||
id,
|
||||
title: "New end node",
|
||||
@@ -119,7 +119,7 @@ describe("#addDocumentToStructure", () => {
|
||||
|
||||
it("should add with an index", async () => {
|
||||
const collection = await buildCollection();
|
||||
const id = uuidv4();
|
||||
const id = randomUUID();
|
||||
const newDocument = await buildDocument({
|
||||
id,
|
||||
title: "New end node",
|
||||
@@ -136,7 +136,7 @@ describe("#addDocumentToStructure", () => {
|
||||
const document = await buildDocument({ collectionId: collection.id });
|
||||
await collection.reload();
|
||||
|
||||
const id = uuidv4();
|
||||
const id = randomUUID();
|
||||
const newDocument = await buildDocument({
|
||||
id,
|
||||
title: "New end node",
|
||||
@@ -156,12 +156,12 @@ describe("#addDocumentToStructure", () => {
|
||||
await collection.reload();
|
||||
|
||||
const newDocument = await buildDocument({
|
||||
id: uuidv4(),
|
||||
id: randomUUID(),
|
||||
title: "node",
|
||||
parentDocumentId: document.id,
|
||||
teamId: collection.teamId,
|
||||
});
|
||||
const id = uuidv4();
|
||||
const id = randomUUID();
|
||||
const secondDocument = await buildDocument({
|
||||
id,
|
||||
title: "New start node",
|
||||
@@ -239,9 +239,9 @@ describe("#addDocumentToStructure", () => {
|
||||
describe("options: documentJson", () => {
|
||||
it("should append supplied json over document's own", async () => {
|
||||
const collection = await buildCollection();
|
||||
const id = uuidv4();
|
||||
const id = randomUUID();
|
||||
const newDocument = await buildDocument({
|
||||
id: uuidv4(),
|
||||
id: randomUUID(),
|
||||
title: "New end node",
|
||||
parentDocumentId: null,
|
||||
teamId: collection.teamId,
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import { faker } from "@faker-js/faker";
|
||||
import { v4 as uuid } from "uuid";
|
||||
import { randomUUID } from "crypto";
|
||||
import { TeamPreference } from "@shared/types";
|
||||
import { buildDocument, buildTeam } from "@server/test/factories";
|
||||
import User from "../User";
|
||||
@@ -40,7 +40,7 @@ describe("Model", () => {
|
||||
});
|
||||
|
||||
it("should return full array if value changed", async () => {
|
||||
const collaboratorId = uuid();
|
||||
const collaboratorId = randomUUID();
|
||||
const document = await buildDocument();
|
||||
const prev = document.collaboratorIds;
|
||||
|
||||
|
||||
@@ -1,12 +1,12 @@
|
||||
import { v4 as uuidv4 } from "uuid";
|
||||
import { randomUUID } from "crypto";
|
||||
import env from "@server/env";
|
||||
import SubscriptionHelper from "./SubscriptionHelper";
|
||||
|
||||
describe("SubscriptionHelper", () => {
|
||||
describe("unsubscribeUrl", () => {
|
||||
it("should return a valid unsubscribe URL", () => {
|
||||
const userId = uuidv4();
|
||||
const documentId = uuidv4();
|
||||
const userId = randomUUID();
|
||||
const documentId = randomUUID();
|
||||
|
||||
const unsubscribeUrl = SubscriptionHelper.unsubscribeUrl(
|
||||
userId,
|
||||
|
||||
@@ -9,7 +9,7 @@ import {
|
||||
Transaction,
|
||||
UniqueConstraintError,
|
||||
} from "sequelize";
|
||||
import { v4 as uuidv4 } from "uuid";
|
||||
import { randomUUID } from "crypto";
|
||||
import { randomElement } from "@shared/random";
|
||||
import { ImportInput, ImportTaskInput } from "@shared/schema";
|
||||
import {
|
||||
@@ -514,7 +514,7 @@ export default abstract class ImportsProcessor<
|
||||
const json = node.toJSON() as ProsemirrorData;
|
||||
const attrs = json.attrs ?? {};
|
||||
|
||||
attrs.id = uuidv4();
|
||||
attrs.id = randomUUID();
|
||||
attrs.actorId = actorId;
|
||||
|
||||
const externalId = attrs.modelId as string;
|
||||
@@ -597,7 +597,7 @@ export default abstract class ImportsProcessor<
|
||||
}
|
||||
}
|
||||
|
||||
idMap[externalId] = internalId ?? uuidv4();
|
||||
idMap[externalId] = internalId ?? randomUUID();
|
||||
return idMap[externalId];
|
||||
}
|
||||
|
||||
|
||||
@@ -4,7 +4,7 @@ import truncate from "lodash/truncate";
|
||||
import uniqBy from "lodash/uniqBy";
|
||||
import { Fragment, Node } from "prosemirror-model";
|
||||
import { Transaction, WhereOptions } from "sequelize";
|
||||
import { v4 as uuidv4 } from "uuid";
|
||||
import { randomUUID } from "crypto";
|
||||
import { ImportTaskInput, ImportTaskOutput } from "@shared/schema";
|
||||
import {
|
||||
AttachmentPreset,
|
||||
@@ -290,7 +290,7 @@ export default abstract class APIImportTask<
|
||||
|
||||
await sequelize.transaction(async (transaction) => {
|
||||
const dbPromises = attachmentsData.map(async (item) => {
|
||||
const modelId = uuidv4();
|
||||
const modelId = randomUUID();
|
||||
const acl = AttachmentHelper.presetToAcl(
|
||||
AttachmentPreset.DocumentAttachment
|
||||
);
|
||||
|
||||
@@ -3,7 +3,7 @@ import fs from "fs-extra";
|
||||
import find from "lodash/find";
|
||||
import mime from "mime-types";
|
||||
import { Fragment, Node } from "prosemirror-model";
|
||||
import { v4 as uuidv4 } from "uuid";
|
||||
import { randomUUID } from "crypto";
|
||||
import { ProsemirrorData } from "@shared/types";
|
||||
import { schema, serializer } from "@server/editor";
|
||||
import Logger from "@server/logging/Logger";
|
||||
@@ -72,7 +72,7 @@ export default class ImportJSONTask extends ImportTask {
|
||||
collectionId: string
|
||||
) {
|
||||
Object.values(documents).forEach((node) => {
|
||||
const id = uuidv4();
|
||||
const id = randomUUID();
|
||||
output.documents.push({
|
||||
...node,
|
||||
path: "",
|
||||
@@ -101,7 +101,7 @@ export default class ImportJSONTask extends ImportTask {
|
||||
[id: string]: AttachmentJSONExport;
|
||||
}) {
|
||||
Object.values(attachments).forEach((node) => {
|
||||
const id = uuidv4();
|
||||
const id = randomUUID();
|
||||
const mimeType = mime.lookup(node.key) || "application/octet-stream";
|
||||
|
||||
output.attachments.push({
|
||||
@@ -128,7 +128,7 @@ export default class ImportJSONTask extends ImportTask {
|
||||
throw new Error(`Could not parse ${node.path}. ${err.message}`);
|
||||
}
|
||||
|
||||
const collectionId = uuidv4();
|
||||
const collectionId = randomUUID();
|
||||
|
||||
output.collections.push({
|
||||
...item.collection,
|
||||
|
||||
@@ -2,7 +2,7 @@ import path from "path";
|
||||
import fs from "fs-extra";
|
||||
import escapeRegExp from "lodash/escapeRegExp";
|
||||
import mime from "mime-types";
|
||||
import { v4 as uuidv4 } from "uuid";
|
||||
import { randomUUID } from "crypto";
|
||||
import documentImporter from "@server/commands/documentImporter";
|
||||
import { createContext } from "@server/context";
|
||||
import Logger from "@server/logging/Logger";
|
||||
@@ -66,7 +66,7 @@ export default class ImportMarkdownZipTask extends ImportTask {
|
||||
return parseNodeChildren(child.children, collectionId);
|
||||
}
|
||||
|
||||
const id = uuidv4();
|
||||
const id = randomUUID();
|
||||
|
||||
// this is an attachment
|
||||
if (
|
||||
@@ -144,7 +144,7 @@ export default class ImportMarkdownZipTask extends ImportTask {
|
||||
// All nodes in the root level should be collections
|
||||
for (const node of tree) {
|
||||
if (node.children.length > 0) {
|
||||
const collectionId = uuidv4();
|
||||
const collectionId = randomUUID();
|
||||
output.collections.push({
|
||||
id: collectionId,
|
||||
name: node.title,
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { v4 as uuidv4 } from "uuid";
|
||||
import { randomUUID } from "crypto";
|
||||
import { Team } from "@server/models";
|
||||
import { Buckets } from "@server/models/helpers/AttachmentHelper";
|
||||
import FileStorage from "@server/storage/files";
|
||||
@@ -23,7 +23,7 @@ export default class UploadTeamAvatarTask extends BaseTask<Props> {
|
||||
|
||||
const res = await FileStorage.storeFromUrl(
|
||||
props.avatarUrl,
|
||||
`${Buckets.avatars}/${team.id}/${uuidv4()}`,
|
||||
`${Buckets.avatars}/${team.id}/${randomUUID()}`,
|
||||
"public-read"
|
||||
);
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { v4 as uuidv4 } from "uuid";
|
||||
import { randomUUID } from "crypto";
|
||||
import { User } from "@server/models";
|
||||
import { Buckets } from "@server/models/helpers/AttachmentHelper";
|
||||
import FileStorage from "@server/storage/files";
|
||||
@@ -23,7 +23,7 @@ export default class UploadUserAvatarTask extends BaseTask<Props> {
|
||||
|
||||
const res = await FileStorage.storeFromUrl(
|
||||
props.avatarUrl,
|
||||
`${Buckets.avatars}/${user.id}/${uuidv4()}`,
|
||||
`${Buckets.avatars}/${user.id}/${randomUUID()}`,
|
||||
"public-read"
|
||||
);
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import Router from "koa-router";
|
||||
import { WhereOptions } from "sequelize";
|
||||
import { v4 as uuidv4 } from "uuid";
|
||||
import { randomUUID } from "crypto";
|
||||
import { AttachmentPreset } from "@shared/types";
|
||||
import { bytesToHumanReadable, getFileNameFromUrl } from "@shared/utils/files";
|
||||
import { AttachmentValidation } from "@shared/validations";
|
||||
@@ -113,7 +113,7 @@ router.post(
|
||||
);
|
||||
}
|
||||
|
||||
const modelId = uuidv4();
|
||||
const modelId = randomUUID();
|
||||
const acl = AttachmentHelper.presetToAcl(preset);
|
||||
const key = AttachmentHelper.getKey({
|
||||
acl,
|
||||
@@ -185,7 +185,7 @@ router.post(
|
||||
authorize(user, "update", document);
|
||||
|
||||
const name = getFileNameFromUrl(url) ?? "file";
|
||||
const modelId = uuidv4();
|
||||
const modelId = randomUUID();
|
||||
const acl = AttachmentHelper.presetToAcl(preset);
|
||||
const key = AttachmentHelper.getKey({
|
||||
acl,
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
import { faker } from "@faker-js/faker";
|
||||
import { v4 as uuidv4 } from "uuid";
|
||||
import { randomUUID } from "crypto";
|
||||
import { buildUser, buildTeam } from "@server/test/factories";
|
||||
import { getTestServer, setSelfHosted } from "@server/test/support";
|
||||
|
||||
const mockTeamInSessionId = uuidv4();
|
||||
const mockTeamInSessionId = randomUUID();
|
||||
|
||||
jest.mock("@server/utils/authentication", () => ({
|
||||
getSessionsInCookie() {
|
||||
@@ -107,7 +107,7 @@ describe("#auth.config", () => {
|
||||
authenticationProviders: [
|
||||
{
|
||||
name: "slack",
|
||||
providerId: uuidv4(),
|
||||
providerId: randomUUID(),
|
||||
},
|
||||
],
|
||||
});
|
||||
@@ -130,7 +130,7 @@ describe("#auth.config", () => {
|
||||
authenticationProviders: [
|
||||
{
|
||||
name: "slack",
|
||||
providerId: uuidv4(),
|
||||
providerId: randomUUID(),
|
||||
},
|
||||
],
|
||||
});
|
||||
@@ -153,7 +153,7 @@ describe("#auth.config", () => {
|
||||
authenticationProviders: [
|
||||
{
|
||||
name: "slack",
|
||||
providerId: uuidv4(),
|
||||
providerId: randomUUID(),
|
||||
},
|
||||
],
|
||||
});
|
||||
@@ -177,7 +177,7 @@ describe("#auth.config", () => {
|
||||
authenticationProviders: [
|
||||
{
|
||||
name: "slack",
|
||||
providerId: uuidv4(),
|
||||
providerId: randomUUID(),
|
||||
enabled: false,
|
||||
},
|
||||
],
|
||||
@@ -201,7 +201,7 @@ describe("#auth.config", () => {
|
||||
authenticationProviders: [
|
||||
{
|
||||
name: "slack",
|
||||
providerId: uuidv4(),
|
||||
providerId: randomUUID(),
|
||||
},
|
||||
],
|
||||
});
|
||||
@@ -220,7 +220,7 @@ describe("#auth.config", () => {
|
||||
authenticationProviders: [
|
||||
{
|
||||
name: "slack",
|
||||
providerId: uuidv4(),
|
||||
providerId: randomUUID(),
|
||||
},
|
||||
],
|
||||
});
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { v4 as uuidv4 } from "uuid";
|
||||
import { randomUUID } from "crypto";
|
||||
import { buildUser, buildAdmin, buildTeam } from "@server/test/factories";
|
||||
import { getTestServer, setSelfHosted } from "@server/test/support";
|
||||
|
||||
@@ -77,7 +77,7 @@ describe("#authenticationProviders.update", () => {
|
||||
});
|
||||
const googleProvider = await team.$create("authenticationProvider", {
|
||||
name: "google",
|
||||
providerId: uuidv4(),
|
||||
providerId: randomUUID(),
|
||||
});
|
||||
const res = await server.post("/api/authenticationProviders.update", {
|
||||
body: {
|
||||
|
||||
@@ -12,7 +12,7 @@ import remove from "lodash/remove";
|
||||
import uniq from "lodash/uniq";
|
||||
import mime from "mime-types";
|
||||
import { Op, ScopeOptions, Sequelize, WhereOptions } from "sequelize";
|
||||
import { v4 as uuidv4 } from "uuid";
|
||||
import { randomUUID } from "crypto";
|
||||
import { NavigationNode, StatusFilter, UserRole } from "@shared/types";
|
||||
import { subtractDate } from "@shared/utils/date";
|
||||
import slugify from "@shared/utils/slugify";
|
||||
@@ -1607,7 +1607,7 @@ router.post(
|
||||
|
||||
const key = AttachmentHelper.getKey({
|
||||
acl,
|
||||
id: uuidv4(),
|
||||
id: randomUUID(),
|
||||
name: fileName,
|
||||
userId: user.id,
|
||||
});
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import queryString from "query-string";
|
||||
import { v4 as uuidv4 } from "uuid";
|
||||
import { randomUUID } from "crypto";
|
||||
import { randomElement } from "@shared/random";
|
||||
import { NotificationEventType } from "@shared/types";
|
||||
import NotificationSettingsHelper from "@server/models/helpers/NotificationSettingsHelper";
|
||||
@@ -335,7 +335,7 @@ describe("#notifications.pixel", () => {
|
||||
it("should return 404 for notification that does not exist", async () => {
|
||||
const res = await server.get(
|
||||
`/api/notifications.pixel?${queryString.stringify({
|
||||
id: uuidv4(),
|
||||
id: randomUUID(),
|
||||
token: "invalid-token",
|
||||
})}`
|
||||
);
|
||||
|
||||
@@ -4,7 +4,7 @@ import isNull from "lodash/isNull";
|
||||
import { Node } from "prosemirror-model";
|
||||
import { InferCreationAttributes } from "sequelize";
|
||||
import { DeepPartial } from "utility-types";
|
||||
import { v4 as uuidv4 } from "uuid";
|
||||
import { randomUUID } from "crypto";
|
||||
import { randomString } from "@shared/random";
|
||||
import {
|
||||
CollectionPermission,
|
||||
@@ -282,7 +282,7 @@ export async function buildIntegration(overrides: Partial<Integration> = {}) {
|
||||
type: IntegrationType.Post,
|
||||
events: ["documents.update", "documents.publish"],
|
||||
settings: {
|
||||
serviceTeamId: uuidv4(),
|
||||
serviceTeamId: randomUUID(),
|
||||
},
|
||||
authenticationId: authentication.id,
|
||||
...overrides,
|
||||
@@ -559,7 +559,7 @@ export async function buildAttachment(
|
||||
overrides.documentId = document.id;
|
||||
}
|
||||
|
||||
const id = uuidv4();
|
||||
const id = randomUUID();
|
||||
const acl = overrides.acl || "public-read";
|
||||
const name = fileName || faker.system.fileName();
|
||||
return Attachment.create({
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { v4 } from "uuid";
|
||||
import { randomUUID } from "crypto";
|
||||
import { Scope } from "@shared/types";
|
||||
import { OAuthInterface } from "./OAuthInterface";
|
||||
import {
|
||||
@@ -9,10 +9,10 @@ import {
|
||||
|
||||
describe("OAuthInterface", () => {
|
||||
const user = {
|
||||
id: v4(),
|
||||
id: randomUUID(),
|
||||
};
|
||||
const client = {
|
||||
id: v4(),
|
||||
id: randomUUID(),
|
||||
grants: ["authorization_code", "refresh_token"],
|
||||
redirectUris: ["https://example.com/callback"],
|
||||
};
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import { expect } from "@jest/globals";
|
||||
import { v4 as uuidv4 } from "uuid";
|
||||
import { randomUUID } from "crypto";
|
||||
import env from "@server/env";
|
||||
import parseAttachmentIds from "./parseAttachmentIds";
|
||||
|
||||
@@ -8,7 +8,7 @@ it("should return an empty array with no matches", () => {
|
||||
});
|
||||
|
||||
it("should not return orphaned UUID's", () => {
|
||||
const uuid = uuidv4();
|
||||
const uuid = randomUUID();
|
||||
expect(
|
||||
parseAttachmentIds(`some random text with a uuid ${uuid}
|
||||
|
||||
@@ -17,7 +17,7 @@ it("should not return orphaned UUID's", () => {
|
||||
});
|
||||
|
||||
it("should parse attachment ID from markdown", () => {
|
||||
const uuid = uuidv4();
|
||||
const uuid = randomUUID();
|
||||
const results = parseAttachmentIds(
|
||||
``
|
||||
);
|
||||
@@ -26,7 +26,7 @@ it("should parse attachment ID from markdown", () => {
|
||||
});
|
||||
|
||||
it("should parse attachment ID from markdown with additional query params", () => {
|
||||
const uuid = uuidv4();
|
||||
const uuid = randomUUID();
|
||||
const results = parseAttachmentIds(
|
||||
``
|
||||
);
|
||||
@@ -35,7 +35,7 @@ it("should parse attachment ID from markdown with additional query params", () =
|
||||
});
|
||||
|
||||
it("should parse attachment ID from markdown with fully qualified url", () => {
|
||||
const uuid = uuidv4();
|
||||
const uuid = randomUUID();
|
||||
const results = parseAttachmentIds(
|
||||
``
|
||||
);
|
||||
@@ -44,7 +44,7 @@ it("should parse attachment ID from markdown with fully qualified url", () => {
|
||||
});
|
||||
|
||||
it("should parse attachment ID from markdown with title", () => {
|
||||
const uuid = uuidv4();
|
||||
const uuid = randomUUID();
|
||||
const results = parseAttachmentIds(
|
||||
``
|
||||
);
|
||||
@@ -53,8 +53,8 @@ it("should parse attachment ID from markdown with title", () => {
|
||||
});
|
||||
|
||||
it("should parse multiple attachment IDs from markdown", () => {
|
||||
const uuid = uuidv4();
|
||||
const uuid2 = uuidv4();
|
||||
const uuid = randomUUID();
|
||||
const uuid2 = randomUUID();
|
||||
const results =
|
||||
parseAttachmentIds(`
|
||||
|
||||
@@ -67,7 +67,7 @@ some text
|
||||
});
|
||||
|
||||
it("should parse attachment ID from html", () => {
|
||||
const uuid = uuidv4();
|
||||
const uuid = randomUUID();
|
||||
const results = parseAttachmentIds(
|
||||
`<img src="/api/attachments.redirect?id=${uuid}" />`
|
||||
);
|
||||
@@ -76,7 +76,7 @@ it("should parse attachment ID from html", () => {
|
||||
});
|
||||
|
||||
it("should parse attachment ID from html with fully qualified url", () => {
|
||||
const uuid = uuidv4();
|
||||
const uuid = randomUUID();
|
||||
const results = parseAttachmentIds(
|
||||
`<img src="${env.URL}/api/attachments.redirect?id=${uuid}" />`
|
||||
);
|
||||
|
||||
@@ -1,65 +1,65 @@
|
||||
import { v4 as uuidv4 } from "uuid";
|
||||
import { randomUUID } from "crypto";
|
||||
import { Buckets } from "./models/helpers/AttachmentHelper";
|
||||
import { ValidateKey } from "./validation";
|
||||
|
||||
describe("#ValidateKey.isValid", () => {
|
||||
it("should return false if number of key components are not equal to 4", () => {
|
||||
expect(
|
||||
ValidateKey.isValid(`${Buckets.uploads}/${uuidv4()}/${uuidv4()}`)
|
||||
ValidateKey.isValid(`${Buckets.uploads}/${randomUUID()}/${randomUUID()}`)
|
||||
).toBe(false);
|
||||
expect(
|
||||
ValidateKey.isValid(`${Buckets.uploads}/${uuidv4()}/${uuidv4()}/foo/bar`)
|
||||
ValidateKey.isValid(`${Buckets.uploads}/${randomUUID()}/${randomUUID()}/foo/bar`)
|
||||
).toBe(false);
|
||||
});
|
||||
|
||||
it("should return false if the first key component is not a valid bucket", () => {
|
||||
expect(ValidateKey.isValid(`foo/${uuidv4()}/${uuidv4()}/bar.png`)).toBe(
|
||||
expect(ValidateKey.isValid(`foo/${randomUUID()}/${randomUUID()}/bar.png`)).toBe(
|
||||
false
|
||||
);
|
||||
});
|
||||
|
||||
it("should return false if second and third key components are not UUID", () => {
|
||||
expect(
|
||||
ValidateKey.isValid(`${Buckets.uploads}/foo/${uuidv4()}/bar.png`)
|
||||
ValidateKey.isValid(`${Buckets.uploads}/foo/${randomUUID()}/bar.png`)
|
||||
).toBe(false);
|
||||
expect(
|
||||
ValidateKey.isValid(`${Buckets.uploads}/${uuidv4()}/foo/bar.png`)
|
||||
ValidateKey.isValid(`${Buckets.uploads}/${randomUUID()}/foo/bar.png`)
|
||||
).toBe(false);
|
||||
});
|
||||
|
||||
it("should return true successfully validating key", () => {
|
||||
expect(
|
||||
ValidateKey.isValid(`${Buckets.public}/${uuidv4()}/${uuidv4()}/foo.png`)
|
||||
ValidateKey.isValid(`${Buckets.public}/${randomUUID()}/${randomUUID()}/foo.png`)
|
||||
).toBe(true);
|
||||
expect(
|
||||
ValidateKey.isValid(`${Buckets.uploads}/${uuidv4()}/${uuidv4()}/foo.png`)
|
||||
ValidateKey.isValid(`${Buckets.uploads}/${randomUUID()}/${randomUUID()}/foo.png`)
|
||||
).toBe(true);
|
||||
expect(
|
||||
ValidateKey.isValid(`${Buckets.avatars}/${uuidv4()}/${uuidv4()}`)
|
||||
ValidateKey.isValid(`${Buckets.avatars}/${randomUUID()}/${randomUUID()}`)
|
||||
).toBe(true);
|
||||
});
|
||||
});
|
||||
|
||||
describe("#ValidateKey.sanitize", () => {
|
||||
it("should sanitize malicious looking keys", () => {
|
||||
const uuid1 = uuidv4();
|
||||
const uuid2 = uuidv4();
|
||||
const uuid1 = randomUUID();
|
||||
const uuid2 = randomUUID();
|
||||
expect(
|
||||
ValidateKey.sanitize(`public/${uuid1}/${uuid2}/~\.\u0000\malicious_key`)
|
||||
).toEqual(`public/${uuid1}/${uuid2}/~.malicious_key`);
|
||||
});
|
||||
|
||||
it("should remove potential path traversal", () => {
|
||||
const uuid1 = uuidv4();
|
||||
const uuid2 = uuidv4();
|
||||
const uuid1 = randomUUID();
|
||||
const uuid2 = randomUUID();
|
||||
expect(
|
||||
ValidateKey.sanitize(`public/${uuid1}/${uuid2}/../../malicious_key`)
|
||||
).toEqual(`public/${uuid1}/${uuid2}/malicious_key`);
|
||||
});
|
||||
|
||||
it("should remove problematic characters", () => {
|
||||
const uuid1 = uuidv4();
|
||||
const uuid2 = uuidv4();
|
||||
const uuid1 = randomUUID();
|
||||
const uuid2 = randomUUID();
|
||||
expect(ValidateKey.sanitize(`public/${uuid1}/${uuid2}/test#:*?`)).toEqual(
|
||||
`public/${uuid1}/${uuid2}/test`
|
||||
);
|
||||
|
||||
Reference in New Issue
Block a user