diff --git a/app/components/HoverPreviewDocument.tsx b/app/components/HoverPreviewDocument.tsx
index 7786f32a6..0edaa96dc 100644
--- a/app/components/HoverPreviewDocument.tsx
+++ b/app/components/HoverPreviewDocument.tsx
@@ -9,7 +9,7 @@ import useStores from "~/hooks/useStores";
type Props = {
url: string;
- children: (arg0: React.ReactNode) => React.ReactNode;
+ children: (content: React.ReactNode) => React.ReactNode;
};
function HoverPreviewDocument({ url, children }: Props) {
@@ -23,20 +23,27 @@ function HoverPreviewDocument({ url, children }: Props) {
const document = slug ? documents.getByUrl(slug) : undefined;
if (!document) return null;
- return children(
-
- {document.titleWithDefault}
-
+ return (
+ <>
+ {children(
+
+ {document.titleWithDefault}
+
- }>
-
-
-
+ }>
+
+
+
+ )}
+ >
);
}
@@ -49,5 +56,4 @@ const Heading = styled.h2`
color: ${(props) => props.theme.text};
`;
-// @ts-expect-error ts-migrate(2345) FIXME: Argument of type '({ url, children }: Props) => Re... Remove this comment to see the full error message
export default observer(HoverPreviewDocument);
diff --git a/app/scenes/Document/components/Document.tsx b/app/scenes/Document/components/Document.tsx
index 6810fd792..c751ae87c 100644
--- a/app/scenes/Document/components/Document.tsx
+++ b/app/scenes/Document/components/Document.tsx
@@ -497,8 +497,6 @@ class DocumentScene extends React.Component {
}
savingIsDisabled={document.isSaving || this.isEmpty}
sharedTree={this.props.sharedTree}
- // @ts-expect-error ts-migrate(2322) FIXME: Type '{ document: Document; shareId: any; isRevisi... Remove this comment to see the full error message
- goBack={this.goBack}
onSelectTemplate={this.replaceDocument}
onSave={this.onSave}
headings={headings}
diff --git a/app/scenes/Document/components/Editor.tsx b/app/scenes/Document/components/Editor.tsx
index c398fd0b8..dc1a04d8c 100644
--- a/app/scenes/Document/components/Editor.tsx
+++ b/app/scenes/Document/components/Editor.tsx
@@ -124,7 +124,7 @@ class DocumentEditor extends React.Component {
{...rest}
/>
{!readOnly && }
- {this.activeLinkEvent && !shareId && readOnly && (
+ {this.activeLinkEvent && !shareId && (
void;
- onDiscard: () => void;
onSave: (options: {
done?: boolean;
publish?: boolean;
diff --git a/server/commands/collectionExporter.ts b/server/commands/collectionExporter.ts
index fa12f29e5..6e3864462 100644
--- a/server/commands/collectionExporter.ts
+++ b/server/commands/collectionExporter.ts
@@ -27,6 +27,7 @@ export default async function collectionExporter({
userId: user.id,
teamId: user.teamId,
});
+
// Event is consumed on worker in queues/processors/exports
await Event.create({
name: collection ? "collections.export" : "collections.export_all",
@@ -36,6 +37,7 @@ export default async function collectionExporter({
modelId: fileOperation.id,
ip,
});
+
fileOperation.user = user;
fileOperation.collection = collection;
return fileOperation;
diff --git a/server/commands/documentMover.test.ts b/server/commands/documentMover.test.ts
index c91bc360b..4c9954419 100644
--- a/server/commands/documentMover.test.ts
+++ b/server/commands/documentMover.test.ts
@@ -134,6 +134,7 @@ describe("documentMover", () => {
title: "Child document",
text: `content `,
});
+
await collection.addDocumentToStructure(newDocument);
await documentMover({
user,
@@ -143,9 +144,11 @@ describe("documentMover", () => {
index: 0,
ip,
});
+
// check document ids where updated
await newDocument.reload();
expect(newDocument.collectionId).toBe(newCollection.id);
+
// check new attachment was created pointint to same key
const attachmentIds = parseAttachmentIds(newDocument.text);
const newAttachment = await Attachment.findByPk(attachmentIds[0]);
diff --git a/server/commands/documentMover.ts b/server/commands/documentMover.ts
index 67311f95b..5301d568f 100644
--- a/server/commands/documentMover.ts
+++ b/server/commands/documentMover.ts
@@ -1,9 +1,12 @@
+import { Transaction } from "sequelize";
import { Document, Attachment, Collection, User, Event } from "@server/models";
import parseAttachmentIds from "@server/utils/parseAttachmentIds";
import { sequelize } from "../sequelize";
-// @ts-expect-error ts-migrate(7006) FIXME: Parameter 'options' implicitly has an 'any' type.
-async function copyAttachments(document: Document, options) {
+async function copyAttachments(
+ document: Document,
+ options?: { transaction?: Transaction }
+) {
// @ts-expect-error ts-migrate(2339) FIXME: Property 'text' does not exist on type 'Document'.
let text = document.text;
// @ts-expect-error ts-migrate(2339) FIXME: Property 'id' does not exist on type 'Document'.
@@ -41,7 +44,6 @@ export default async function documentMover({
user,
document,
collectionId,
- // @ts-expect-error ts-migrate(2322) FIXME: Type 'null' is not assignable to type 'string'.
parentDocumentId = null,
// convert undefined to null so parentId comparison treats them as equal
index,
@@ -51,12 +53,11 @@ export default async function documentMover({
user: User;
document: Document;
collectionId: string;
- parentDocumentId?: string;
+ parentDocumentId?: string | null;
index?: number;
ip: string;
}) {
- // @ts-expect-error ts-migrate(7034) FIXME: Variable 'transaction' implicitly has type 'any' i... Remove this comment to see the full error message
- let transaction;
+ let transaction: Transaction | undefined;
// @ts-expect-error ts-migrate(2339) FIXME: Property 'collectionId' does not exist on type 'Do... Remove this comment to see the full error message
const collectionChanged = collectionId !== document.collectionId;
const result = {
@@ -86,6 +87,7 @@ export default async function documentMover({
} else {
try {
transaction = await sequelize.transaction();
+
// remove from original collection
// @ts-expect-error ts-migrate(2339) FIXME: Property 'collectionId' does not exist on type 'Do... Remove this comment to see the full error message
const collection = await Collection.findByPk(document.collectionId, {
@@ -98,6 +100,7 @@ export default async function documentMover({
] = (await collection.removeDocumentInStructure(document, {
save: false,
})) || [undefined, index];
+
// if we're reordering from within the same parent
// the original and destination collection are the same,
// so when the initial item is removed above, the list will reduce by 1.
@@ -166,7 +169,6 @@ export default async function documentMover({
childDocuments.map(async (child) => {
await loopChildren(child.id);
child.text = await copyAttachments(child, {
- // @ts-expect-error ts-migrate(7005) FIXME: Variable 'transaction' implicitly has an 'any' typ... Remove this comment to see the full error message
transaction,
});
child.collectionId = collectionId;
@@ -190,7 +192,10 @@ export default async function documentMover({
document.collection = newCollection;
// @ts-expect-error ts-migrate(2345) FIXME: Argument of type 'Document' is not assignable to p... Remove this comment to see the full error message
result.documents.push(document);
- await transaction.commit();
+
+ if (transaction) {
+ await transaction.commit();
+ }
} catch (err) {
if (transaction) {
await transaction.rollback();
diff --git a/server/utils/parseAttachmentIds.ts b/server/utils/parseAttachmentIds.ts
index cce40c788..d69be094c 100644
--- a/server/utils/parseAttachmentIds.ts
+++ b/server/utils/parseAttachmentIds.ts
@@ -1,7 +1,11 @@
+import { compact } from "lodash";
+
const attachmentRegex = /\/api\/attachments\.redirect\?id=(?[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12})/gi;
-export default function parseAttachmentIds(text: any): string[] {
- return [...text.matchAll(attachmentRegex)].map(
- (match) => match.groups && match.groups.id
+export default function parseAttachmentIds(text: string): string[] {
+ return compact(
+ [...text.matchAll(attachmentRegex)].map(
+ (match) => match.groups && match.groups.id
+ )
);
}
diff --git a/server/utils/passport.ts b/server/utils/passport.ts
index 9e89d1c0d..b1ae3d919 100644
--- a/server/utils/passport.ts
+++ b/server/utils/passport.ts
@@ -1,51 +1,52 @@
import crypto from "crypto";
import { addMinutes, subMinutes } from "date-fns";
import fetch from "fetch-with-proxy";
-import { Request } from "koa";
+import { Context } from "koa";
import { OAuthStateMismatchError } from "../errors";
import { getCookieDomain } from "./domains";
export class StateStore {
key = "state";
- store = (req: Request, callback: () => void) => {
+ store = (
+ ctx: Context,
+ callback: (err: Error | null, state: string) => void
+ ) => {
// Produce a random string as state
const state = crypto.randomBytes(8).toString("hex");
- // @ts-expect-error ts-migrate(2339) FIXME: Property 'cookies' does not exist on type 'Request... Remove this comment to see the full error message
- req.cookies.set(this.key, state, {
+ ctx.cookies.set(this.key, state, {
httpOnly: false,
expires: addMinutes(new Date(), 10),
- domain: getCookieDomain(req.hostname),
+ domain: getCookieDomain(ctx.hostname),
});
- // @ts-expect-error ts-migrate(2554) FIXME: Expected 0 arguments, but got 2.
+
callback(null, state);
};
- verify = (req: Request, providedState: string, callback: () => void) => {
- // @ts-expect-error ts-migrate(2339) FIXME: Property 'cookies' does not exist on type 'Request... Remove this comment to see the full error message
- const state = req.cookies.get(this.key);
+ verify = (
+ ctx: Context,
+ providedState: string,
+ callback: (err: Error | null, success?: boolean) => void
+ ) => {
+ const state = ctx.cookies.get(this.key);
if (!state) {
return callback(
- // @ts-expect-error ts-migrate(2554) FIXME: Expected 0 arguments, but got 1.
- new OAuthStateMismatchError("State not return in OAuth flow")
+ OAuthStateMismatchError("State not return in OAuth flow")
);
}
- // @ts-expect-error ts-migrate(2339) FIXME: Property 'cookies' does not exist on type 'Request... Remove this comment to see the full error message
- req.cookies.set(this.key, "", {
+ ctx.cookies.set(this.key, "", {
httpOnly: false,
expires: subMinutes(new Date(), 1),
- domain: getCookieDomain(req.hostname),
+ domain: getCookieDomain(ctx.hostname),
});
if (state !== providedState) {
- // @ts-expect-error ts-migrate(2554) FIXME: Expected 0 arguments, but got 1.
- return callback(new OAuthStateMismatchError());
+ return callback(OAuthStateMismatchError());
}
- // @ts-expect-error ts-migrate(2554) FIXME: Expected 0 arguments, but got 2.
callback(null, true);
};
}
diff --git a/server/utils/removeIndexCollision.ts b/server/utils/removeIndexCollision.ts
index bd1915c8d..a0025ac5f 100644
--- a/server/utils/removeIndexCollision.ts
+++ b/server/utils/removeIndexCollision.ts
@@ -1,13 +1,13 @@
import fractionalIndex from "fractional-index";
import { Collection } from "@server/models";
import { sequelize, Op } from "../sequelize";
+
/**
*
* @param teamId The team id whose collections has to be fetched
* @param index the index for which collision has to be checked
* @returns An index, if there is collision returns a new index otherwise the same index
*/
-
export default async function removeIndexCollision(
teamId: string,
index: string
diff --git a/server/utils/s3.ts b/server/utils/s3.ts
index d51a006e3..d2e109dd0 100644
--- a/server/utils/s3.ts
+++ b/server/utils/s3.ts
@@ -7,7 +7,7 @@ import Logger from "@server/logging/logger";
const AWS_SECRET_ACCESS_KEY = process.env.AWS_SECRET_ACCESS_KEY;
const AWS_ACCESS_KEY_ID = process.env.AWS_ACCESS_KEY_ID;
-const AWS_REGION = process.env.AWS_REGION;
+const AWS_REGION = process.env.AWS_REGION || "";
const AWS_S3_UPLOAD_BUCKET_NAME = process.env.AWS_S3_UPLOAD_BUCKET_NAME || "";
const AWS_S3_FORCE_PATH_STYLE = process.env.AWS_S3_FORCE_PATH_STYLE !== "false";
const s3 = new AWS.S3({
@@ -25,11 +25,13 @@ const s3 = new AWS.S3({
signatureVersion: "v4",
});
-const hmac = (key: string, message: string, encoding: any) => {
- return crypto
- .createHmac("sha256", key)
- .update(message, "utf8")
- .digest(encoding);
+const hmac = (
+ key: string | Buffer,
+ message: string,
+ encoding?: "base64" | "hex"
+) => {
+ const o = crypto.createHmac("sha256", key).update(message, "utf8");
+ return encoding ? o.digest(encoding) : o.digest();
};
export const makeCredential = () => {
@@ -75,20 +77,17 @@ export const makePolicy = (
],
expiration: format(tomorrow, "yyyy-MM-dd'T'HH:mm:ss'Z'"),
};
+
return Buffer.from(JSON.stringify(policy)).toString("base64");
};
-export const getSignature = (policy: any) => {
- // @ts-expect-error ts-migrate(2554) FIXME: Expected 3 arguments, but got 2.
+export const getSignature = (policy: string) => {
const kDate = hmac(
"AWS4" + AWS_SECRET_ACCESS_KEY,
format(new Date(), "yyyyMMdd")
);
- // @ts-expect-error ts-migrate(2554) FIXME: Expected 3 arguments, but got 2.
const kRegion = hmac(kDate, AWS_REGION);
- // @ts-expect-error ts-migrate(2554) FIXME: Expected 3 arguments, but got 2.
const kService = hmac(kRegion, "s3");
- // @ts-expect-error ts-migrate(2554) FIXME: Expected 3 arguments, but got 2.
const kCredentials = hmac(kService, "aws4_request");
const signature = hmac(kCredentials, policy, "hex");
return signature;
@@ -198,7 +197,6 @@ export const getAWSKeyForFileOp = (teamId: string, name: string) => {
return `${bucket}/${teamId}/${uuidv4()}/${name}-export.zip`;
};
-// @ts-expect-error ts-migrate(7030) FIXME: Not all code paths return a value.
export const getFileByKey = async (key: string) => {
const params = {
Bucket: AWS_S3_UPLOAD_BUCKET_NAME,
@@ -207,10 +205,12 @@ export const getFileByKey = async (key: string) => {
try {
const data = await s3.getObject(params).promise();
- return data.Body;
+ return data.Body || null;
} catch (err) {
Logger.error("Error getting file from S3 by key", err, {
key,
});
}
+
+ return null;
};
diff --git a/server/utils/zip.ts b/server/utils/zip.ts
index 52e84de55..ad93cd029 100644
--- a/server/utils/zip.ts
+++ b/server/utils/zip.ts
@@ -3,11 +3,11 @@ import JSZip from "jszip";
import tmp from "tmp";
import Logger from "@server/logging/logger";
import { Attachment, Collection, Document } from "@server/models";
+import { NavigationNode } from "~/types";
import { serializeFilename } from "./fs";
import { getFileByKey } from "./s3";
-// @ts-expect-error ts-migrate(7006) FIXME: Parameter 'zip' implicitly has an 'any' type.
-async function addToArchive(zip, documents) {
+async function addToArchive(zip: JSZip, documents: NavigationNode[]) {
for (const doc of documents) {
const document = await Document.findByPk(doc.id);
@@ -39,15 +39,19 @@ async function addToArchive(zip, documents) {
if (doc.children && doc.children.length) {
const folder = zip.folder(title);
- await addToArchive(folder, doc.children);
+
+ if (folder) {
+ await addToArchive(folder, doc.children);
+ }
}
}
}
-// @ts-expect-error ts-migrate(7006) FIXME: Parameter 'zip' implicitly has an 'any' type.
-async function addImageToArchive(zip, key) {
+async function addImageToArchive(zip: JSZip, key: string) {
try {
const img = await getFileByKey(key);
+
+ // @ts-expect-error Blob
zip.file(key, img, {
createFolders: true,
});
@@ -58,8 +62,7 @@ async function addImageToArchive(zip, key) {
}
}
-// @ts-expect-error ts-migrate(7006) FIXME: Parameter 'zip' implicitly has an 'any' type.
-async function archiveToPath(zip) {
+async function archiveToPath(zip: JSZip) {
return new Promise((resolve, reject) => {
tmp.file(
{
@@ -88,7 +91,10 @@ export async function archiveCollections(collections: Collection[]) {
for (const collection of collections) {
if (collection.documentStructure) {
const folder = zip.folder(collection.name);
- await addToArchive(folder, collection.documentStructure);
+
+ if (folder) {
+ await addToArchive(folder, collection.documentStructure);
+ }
}
}
diff --git a/server/validation.ts b/server/validation.ts
index 5dffa124a..4243a1f48 100644
--- a/server/validation.ts
+++ b/server/validation.ts
@@ -4,21 +4,23 @@ import { validateColorHex } from "../shared/utils/color";
import { validateIndexCharacters } from "../shared/utils/indexCharacters";
import { ParamRequiredError, ValidationError } from "./errors";
-export const assertPresent = (value: any, message: string) => {
+export const assertPresent = (value: unknown, message: string) => {
if (value === undefined || value === null || value === "") {
throw ParamRequiredError(message);
}
};
-// @ts-expect-error ts-migrate(7006) FIXME: Parameter 'value' implicitly has an 'any' type.
-export const assertArray = (value, message) => {
+export const assertArray = (value: unknown, message?: string) => {
if (!isArrayLike(value)) {
throw ValidationError(message);
}
};
-// @ts-expect-error ts-migrate(7006) FIXME: Parameter 'value' implicitly has an 'any' type.
-export const assertIn = (value, options, message) => {
+export const assertIn = (
+ value: string,
+ options: (string | null)[],
+ message?: string
+) => {
if (!options.includes(value)) {
throw ValidationError(message);
}
@@ -34,22 +36,19 @@ export const assertSort = (
}
};
-// @ts-expect-error ts-migrate(7006) FIXME: Parameter 'value' implicitly has an 'any' type.
-export const assertNotEmpty = (value, message) => {
+export const assertNotEmpty = (value: unknown, message?: string) => {
if (value === "") {
throw ValidationError(message);
}
};
-// @ts-expect-error ts-migrate(7006) FIXME: Parameter 'message' implicitly has an 'any' type.
-export const assertEmail = (value = "", message) => {
+export const assertEmail = (value = "", message?: string) => {
if (!validator.isEmail(value)) {
throw ValidationError(message);
}
};
-// @ts-expect-error ts-migrate(7006) FIXME: Parameter 'message' implicitly has an 'any' type.
-export const assertUuid = (value, message) => {
+export const assertUuid = (value: unknown, message?: string) => {
if (typeof value !== "string") {
throw ValidationError(message);
}
@@ -58,8 +57,7 @@ export const assertUuid = (value, message) => {
}
};
-// @ts-expect-error ts-migrate(7006) FIXME: Parameter 'value' implicitly has an 'any' type.
-export const assertPositiveInteger = (value, message) => {
+export const assertPositiveInteger = (value: unknown, message?: string) => {
if (
!validator.isInt(String(value), {
min: 0,
@@ -69,22 +67,23 @@ export const assertPositiveInteger = (value, message) => {
}
};
-// @ts-expect-error ts-migrate(7006) FIXME: Parameter 'value' implicitly has an 'any' type.
-export const assertHexColor = (value, message) => {
+export const assertHexColor = (value: string, message?: string) => {
if (!validateColorHex(value)) {
throw ValidationError(message);
}
};
-// @ts-expect-error ts-migrate(7006) FIXME: Parameter 'value' implicitly has an 'any' type.
-export const assertValueInArray = (value, values, message) => {
+export const assertValueInArray = (
+ value: string,
+ values: string[],
+ message?: string
+) => {
if (!values.includes(value)) {
throw ValidationError(message);
}
};
-// @ts-expect-error ts-migrate(7006) FIXME: Parameter 'value' implicitly has an 'any' type.
-export const assertIndexCharacters = (value, message) => {
+export const assertIndexCharacters = (value: string, message?: string) => {
if (!validateIndexCharacters(value)) {
throw ValidationError(message);
}