@@ -14,9 +14,7 @@ export function getAllowedDomains(): string[] {
|
||||
|
||||
export async function signIn(
|
||||
ctx: Context,
|
||||
// @ts-expect-error ts-migrate(2749) FIXME: 'User' refers to a value, but is being used as a t... Remove this comment to see the full error message
|
||||
user: User,
|
||||
// @ts-expect-error ts-migrate(2749) FIXME: 'Team' refers to a value, but is being used as a t... Remove this comment to see the full error message
|
||||
team: Team,
|
||||
service: string,
|
||||
_isNewUser = false,
|
||||
|
||||
@@ -11,15 +11,19 @@ export default async function collectionIndexing(teamId: string) {
|
||||
//no point in maintaining index of deleted collections.
|
||||
attributes: ["id", "index", "name"],
|
||||
});
|
||||
// @ts-expect-error ts-migrate(7006) FIXME: Parameter 'collection' implicitly has an 'any' typ... Remove this comment to see the full error message
|
||||
let sortableCollections = collections.map((collection) => {
|
||||
return [collection, collection.index];
|
||||
});
|
||||
|
||||
let sortableCollections: [Collection, string | null][] = collections.map(
|
||||
(collection) => {
|
||||
return [collection, collection.index];
|
||||
}
|
||||
);
|
||||
|
||||
sortableCollections = naturalSort(
|
||||
sortableCollections,
|
||||
// @ts-expect-error ts-migrate(2345) FIXME: Argument of type '(collection: any) => any' is not... Remove this comment to see the full error message
|
||||
(collection) => collection[0].name
|
||||
);
|
||||
|
||||
//for each collection with null index, use previous collection index to create new index
|
||||
let previousCollectionIndex = null;
|
||||
|
||||
@@ -34,7 +38,6 @@ export default async function collectionIndexing(teamId: string) {
|
||||
}
|
||||
|
||||
const indexedCollections = {};
|
||||
// @ts-expect-error ts-migrate(7006) FIXME: Parameter 'collection' implicitly has an 'any' typ... Remove this comment to see the full error message
|
||||
sortableCollections.forEach((collection) => {
|
||||
indexedCollections[collection[0].id] = collection[0].index;
|
||||
});
|
||||
|
||||
@@ -15,6 +15,7 @@ describe("serializeFilename", () => {
|
||||
);
|
||||
});
|
||||
});
|
||||
|
||||
describe("deserializeFilename", () => {
|
||||
it("should deserialize forward slashes", () => {
|
||||
expect(deserializeFilename("%2F")).toBe("/");
|
||||
|
||||
@@ -1,44 +1,39 @@
|
||||
import { subMinutes } from "date-fns";
|
||||
import invariant from "invariant";
|
||||
import JWT from "jsonwebtoken";
|
||||
import { Team, User } from "@server/models";
|
||||
import { AuthenticationError } from "../errors";
|
||||
|
||||
// @ts-expect-error ts-migrate(7006) FIXME: Parameter 'token' implicitly has an 'any' type.
|
||||
function getJWTPayload(token) {
|
||||
function getJWTPayload(token: string) {
|
||||
let payload;
|
||||
|
||||
try {
|
||||
payload = JWT.decode(token);
|
||||
|
||||
if (!payload) {
|
||||
throw AuthenticationError("Invalid token");
|
||||
}
|
||||
|
||||
return payload as JWT.JwtPayload;
|
||||
} catch (err) {
|
||||
throw AuthenticationError("Unable to decode JWT token");
|
||||
}
|
||||
|
||||
if (!payload) {
|
||||
throw AuthenticationError("Invalid token");
|
||||
}
|
||||
|
||||
return payload;
|
||||
}
|
||||
|
||||
// @ts-expect-error ts-migrate(2749) FIXME: 'User' refers to a value, but is being used as a t... Remove this comment to see the full error message
|
||||
export async function getUserForJWT(token: string): Promise<User> {
|
||||
const payload = getJWTPayload(token);
|
||||
|
||||
// @ts-expect-error ts-migrate(2339) FIXME: Property 'type' does not exist on type 'string | J... Remove this comment to see the full error message
|
||||
if (payload.type === "email-signin") {
|
||||
throw AuthenticationError("Invalid token");
|
||||
}
|
||||
|
||||
// check the token is within it's expiration time
|
||||
// @ts-expect-error ts-migrate(2339) FIXME: Property 'expiresAt' does not exist on type 'strin... Remove this comment to see the full error message
|
||||
if (payload.expiresAt) {
|
||||
// @ts-expect-error ts-migrate(2339) FIXME: Property 'expiresAt' does not exist on type 'strin... Remove this comment to see the full error message
|
||||
if (new Date(payload.expiresAt) < new Date()) {
|
||||
throw AuthenticationError("Expired token");
|
||||
}
|
||||
}
|
||||
|
||||
// @ts-expect-error ts-migrate(2339) FIXME: Property 'id' does not exist on type 'string | Jwt... Remove this comment to see the full error message
|
||||
const user = await User.findByPk(payload.id, {
|
||||
include: [
|
||||
{
|
||||
@@ -48,13 +43,18 @@ export async function getUserForJWT(token: string): Promise<User> {
|
||||
},
|
||||
],
|
||||
});
|
||||
if (!user) {
|
||||
throw AuthenticationError("Invalid token");
|
||||
}
|
||||
|
||||
// @ts-expect-error ts-migrate(2339) FIXME: Property 'type' does not exist on type 'string | J... Remove this comment to see the full error message
|
||||
if (payload.type === "transfer") {
|
||||
// If the user has made a single API request since the transfer token was
|
||||
// created then it's no longer valid, they'll need to sign in again.
|
||||
// @ts-expect-error ts-migrate(2339) FIXME: Property 'createdAt' does not exist on type 'strin... Remove this comment to see the full error message
|
||||
if (user.lastActiveAt > new Date(payload.createdAt)) {
|
||||
if (
|
||||
user.lastActiveAt &&
|
||||
payload.createdAt &&
|
||||
user.lastActiveAt > new Date(payload.createdAt)
|
||||
) {
|
||||
throw AuthenticationError("Token has already been used");
|
||||
}
|
||||
}
|
||||
@@ -68,39 +68,37 @@ export async function getUserForJWT(token: string): Promise<User> {
|
||||
return user;
|
||||
}
|
||||
|
||||
// @ts-expect-error ts-migrate(2749) FIXME: 'User' refers to a value, but is being used as a t... Remove this comment to see the full error message
|
||||
export async function getUserForEmailSigninToken(token: string): Promise<User> {
|
||||
const payload = getJWTPayload(token);
|
||||
|
||||
// @ts-expect-error ts-migrate(2339) FIXME: Property 'type' does not exist on type 'string | J... Remove this comment to see the full error message
|
||||
if (payload.type !== "email-signin") {
|
||||
throw AuthenticationError("Invalid token");
|
||||
}
|
||||
|
||||
// check the token is within it's expiration time
|
||||
// @ts-expect-error ts-migrate(2339) FIXME: Property 'createdAt' does not exist on type 'strin... Remove this comment to see the full error message
|
||||
if (payload.createdAt) {
|
||||
// @ts-expect-error ts-migrate(2339) FIXME: Property 'createdAt' does not exist on type 'strin... Remove this comment to see the full error message
|
||||
if (new Date(payload.createdAt) < subMinutes(new Date(), 10)) {
|
||||
throw AuthenticationError("Expired token");
|
||||
}
|
||||
}
|
||||
|
||||
// @ts-expect-error ts-migrate(2339) FIXME: Property 'id' does not exist on type 'string | Jwt... Remove this comment to see the full error message
|
||||
const user = await User.findByPk(payload.id, {
|
||||
include: [
|
||||
{
|
||||
model: Team,
|
||||
as: "team",
|
||||
required: true,
|
||||
},
|
||||
],
|
||||
});
|
||||
invariant(user, "User not found");
|
||||
|
||||
// if user has signed in at all since the token was created then
|
||||
// it's no longer valid, they'll need a new one.
|
||||
// @ts-expect-error ts-migrate(2339) FIXME: Property 'createdAt' does not exist on type 'strin... Remove this comment to see the full error message
|
||||
if (user.lastSignedInAt > payload.createdAt) {
|
||||
if (
|
||||
user.lastSignedInAt &&
|
||||
payload.createdAt &&
|
||||
user.lastSignedInAt > new Date(payload.createdAt)
|
||||
) {
|
||||
throw AuthenticationError("Token has already been used");
|
||||
}
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import fractionalIndex from "fractional-index";
|
||||
import { Collection } from "@server/models";
|
||||
import { sequelize, Op } from "../sequelize";
|
||||
import { Op, Sequelize } from "sequelize";
|
||||
import Collection from "@server/models/Collection";
|
||||
|
||||
/**
|
||||
*
|
||||
@@ -35,7 +35,7 @@ export default async function removeIndexCollision(
|
||||
attributes: ["id", "index"],
|
||||
limit: 1,
|
||||
order: [
|
||||
sequelize.literal('"collection"."index" collate "C"'),
|
||||
Sequelize.literal('"collection"."index" collate "C"'),
|
||||
["updatedAt", "DESC"],
|
||||
],
|
||||
});
|
||||
|
||||
@@ -7,6 +7,7 @@ import { v4 as uuidv4 } from "uuid";
|
||||
import Logger from "@server/logging/logger";
|
||||
|
||||
const AWS_SECRET_ACCESS_KEY = process.env.AWS_SECRET_ACCESS_KEY;
|
||||
const AWS_S3_UPLOAD_BUCKET_URL = process.env.AWS_S3_UPLOAD_BUCKET_URL || "";
|
||||
const AWS_ACCESS_KEY_ID = process.env.AWS_ACCESS_KEY_ID;
|
||||
const AWS_REGION = process.env.AWS_REGION || "";
|
||||
const AWS_S3_UPLOAD_BUCKET_NAME = process.env.AWS_S3_UPLOAD_BUCKET_NAME || "";
|
||||
@@ -16,13 +17,9 @@ const s3 = new AWS.S3({
|
||||
accessKeyId: AWS_ACCESS_KEY_ID,
|
||||
secretAccessKey: AWS_SECRET_ACCESS_KEY,
|
||||
region: AWS_REGION,
|
||||
// @ts-expect-error ts-migrate(2532) FIXME: Object is possibly 'undefined'.
|
||||
endpoint: process.env.AWS_S3_UPLOAD_BUCKET_URL.includes(
|
||||
AWS_S3_UPLOAD_BUCKET_NAME
|
||||
)
|
||||
endpoint: AWS_S3_UPLOAD_BUCKET_URL.includes(AWS_S3_UPLOAD_BUCKET_NAME)
|
||||
? undefined
|
||||
: // @ts-expect-error ts-migrate(2345) FIXME: Argument of type 'string | undefined' is not assig... Remove this comment to see the full error message
|
||||
new AWS.Endpoint(process.env.AWS_S3_UPLOAD_BUCKET_URL),
|
||||
: new AWS.Endpoint(AWS_S3_UPLOAD_BUCKET_URL),
|
||||
signatureVersion: "v4",
|
||||
});
|
||||
const createPresignedPost = util.promisify(s3.createPresignedPost).bind(s3);
|
||||
@@ -121,14 +118,12 @@ export const getPresignedPost = (
|
||||
export const publicS3Endpoint = (isServerUpload?: boolean) => {
|
||||
// lose trailing slash if there is one and convert fake-s3 url to localhost
|
||||
// for access outside of docker containers in local development
|
||||
// @ts-expect-error ts-migrate(2532) FIXME: Object is possibly 'undefined'.
|
||||
const isDocker = process.env.AWS_S3_UPLOAD_BUCKET_URL.match(/http:\/\/s3:/);
|
||||
const isDocker = AWS_S3_UPLOAD_BUCKET_URL.match(/http:\/\/s3:/);
|
||||
|
||||
// @ts-expect-error ts-migrate(2532) FIXME: Object is possibly 'undefined'.
|
||||
const host = process.env.AWS_S3_UPLOAD_BUCKET_URL.replace(
|
||||
"s3:",
|
||||
"localhost:"
|
||||
).replace(/\/$/, "");
|
||||
const host = AWS_S3_UPLOAD_BUCKET_URL.replace("s3:", "localhost:").replace(
|
||||
/\/$/,
|
||||
""
|
||||
);
|
||||
|
||||
// support old path-style S3 uploads and new virtual host uploads by checking
|
||||
// for the bucket name in the endpoint url before appending.
|
||||
@@ -204,8 +199,7 @@ export const deleteFromS3 = (key: string) => {
|
||||
};
|
||||
|
||||
export const getSignedUrl = async (key: string) => {
|
||||
// @ts-expect-error ts-migrate(2532) FIXME: Object is possibly 'undefined'.
|
||||
const isDocker = process.env.AWS_S3_UPLOAD_BUCKET_URL.match(/http:\/\/s3:/);
|
||||
const isDocker = AWS_S3_UPLOAD_BUCKET_URL.match(/http:\/\/s3:/);
|
||||
const params = {
|
||||
Bucket: AWS_S3_UPLOAD_BUCKET_NAME,
|
||||
Key: key,
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
import chalk from "chalk";
|
||||
import Logger from "@server/logging/logger";
|
||||
import { Team, AuthenticationProvider } from "@server/models";
|
||||
import AuthenticationProvider from "@server/models/AuthenticationProvider";
|
||||
import Team from "@server/models/Team";
|
||||
|
||||
export async function checkMigrations() {
|
||||
if (process.env.DEPLOYMENT === "hosted") {
|
||||
|
||||
@@ -1,7 +1,10 @@
|
||||
import crypto from "crypto";
|
||||
import fetch from "fetch-with-proxy";
|
||||
import invariant from "invariant";
|
||||
import { User, Team, Collection, Document } from "@server/models";
|
||||
import Collection from "@server/models/Collection";
|
||||
import Document from "@server/models/Document";
|
||||
import Team from "@server/models/Team";
|
||||
import User from "@server/models/User";
|
||||
import packageInfo from "../../package.json";
|
||||
import { client } from "../redis";
|
||||
|
||||
|
||||
@@ -2,7 +2,9 @@ import fs from "fs";
|
||||
import JSZip from "jszip";
|
||||
import tmp from "tmp";
|
||||
import Logger from "@server/logging/logger";
|
||||
import { Attachment, Collection, Document } from "@server/models";
|
||||
import Attachment from "@server/models/Attachment";
|
||||
import Collection from "@server/models/Collection";
|
||||
import Document from "@server/models/Document";
|
||||
import { NavigationNode } from "~/types";
|
||||
import { serializeFilename } from "./fs";
|
||||
import { getFileByKey } from "./s3";
|
||||
@@ -31,7 +33,6 @@ async function addToArchive(zip: JSZip, documents: NavigationNode[]) {
|
||||
zip.file(`${title}.md`, text, {
|
||||
date: document.updatedAt,
|
||||
comment: JSON.stringify({
|
||||
pinned: document.pinned,
|
||||
createdAt: document.createdAt,
|
||||
updatedAt: document.updatedAt,
|
||||
}),
|
||||
@@ -84,7 +85,6 @@ async function archiveToPath(zip: JSZip) {
|
||||
});
|
||||
}
|
||||
|
||||
// @ts-expect-error ts-migrate(2749) FIXME: 'Collection' refers to a value, but is being used ... Remove this comment to see the full error message
|
||||
export async function archiveCollections(collections: Collection[]) {
|
||||
const zip = new JSZip();
|
||||
|
||||
|
||||
Reference in New Issue
Block a user