chore: Move last usage of sequelize.transaction to middleware

This commit is contained in:
Tom Moor
2023-07-29 22:30:26 -04:00
parent 07ad5032b4
commit ccdcda372f
4 changed files with 137 additions and 149 deletions

View File

@@ -1,6 +1,6 @@
import Router from "koa-router"; import Router from "koa-router";
import { sequelize } from "@server/database/sequelize";
import auth from "@server/middlewares/authentication"; import auth from "@server/middlewares/authentication";
import { transaction } from "@server/middlewares/transaction";
import validate from "@server/middlewares/validate"; import validate from "@server/middlewares/validate";
import { AuthenticationProvider, Event } from "@server/models"; import { AuthenticationProvider, Event } from "@server/models";
import AuthenticationHelper from "@server/models/helpers/AuthenticationHelper"; import AuthenticationHelper from "@server/models/helpers/AuthenticationHelper";
@@ -36,45 +36,38 @@ router.post(
"authenticationProviders.update", "authenticationProviders.update",
auth({ admin: true }), auth({ admin: true }),
validate(T.AuthenticationProvidersUpdateSchema), validate(T.AuthenticationProvidersUpdateSchema),
transaction(),
async (ctx: APIContext<T.AuthenticationProvidersUpdateReq>) => { async (ctx: APIContext<T.AuthenticationProvidersUpdateReq>) => {
const { transaction } = ctx.state;
const { id, isEnabled } = ctx.input.body; const { id, isEnabled } = ctx.input.body;
const { user } = ctx.state.auth; const { user } = ctx.state.auth;
const authenticationProvider = await sequelize.transaction( const authenticationProvider = await AuthenticationProvider.findByPk(id, {
async (transaction) => { transaction,
const authenticationProvider = await AuthenticationProvider.findByPk( lock: transaction.LOCK.UPDATE,
id, });
{
transaction,
lock: transaction.LOCK.UPDATE,
}
);
authorize(user, "update", authenticationProvider); authorize(user, "update", authenticationProvider);
const enabled = !!isEnabled; const enabled = !!isEnabled;
if (enabled) { if (enabled) {
await authenticationProvider.enable({ transaction }); await authenticationProvider.enable({ transaction });
} else { } else {
await authenticationProvider.disable({ transaction }); await authenticationProvider.disable({ transaction });
} }
await Event.create( await Event.create(
{ {
name: "authenticationProviders.update", name: "authenticationProviders.update",
data: { data: {
enabled, enabled,
}, },
modelId: id, modelId: id,
teamId: user.teamId, teamId: user.teamId,
actorId: user.id, actorId: user.id,
ip: ctx.request.ip, ip: ctx.request.ip,
}, },
{ transaction } { transaction }
);
return authenticationProvider;
}
); );
ctx.body = { ctx.body = {

View File

@@ -12,7 +12,6 @@ import documentLoader from "@server/commands/documentLoader";
import documentMover from "@server/commands/documentMover"; import documentMover from "@server/commands/documentMover";
import documentPermanentDeleter from "@server/commands/documentPermanentDeleter"; import documentPermanentDeleter from "@server/commands/documentPermanentDeleter";
import documentUpdater from "@server/commands/documentUpdater"; import documentUpdater from "@server/commands/documentUpdater";
import { sequelize } from "@server/database/sequelize";
import env from "@server/env"; import env from "@server/env";
import { import {
NotFoundError, NotFoundError,
@@ -24,6 +23,7 @@ import {
import Logger from "@server/logging/Logger"; import Logger from "@server/logging/Logger";
import auth from "@server/middlewares/authentication"; import auth from "@server/middlewares/authentication";
import { rateLimiter } from "@server/middlewares/rateLimiter"; import { rateLimiter } from "@server/middlewares/rateLimiter";
import { transaction } from "@server/middlewares/transaction";
import validate from "@server/middlewares/validate"; import validate from "@server/middlewares/validate";
import { import {
Backlink, Backlink,
@@ -891,7 +891,9 @@ router.post(
"documents.update", "documents.update",
auth(), auth(),
validate(T.DocumentsUpdateSchema), validate(T.DocumentsUpdateSchema),
transaction(),
async (ctx: APIContext<T.DocumentsUpdateReq>) => { async (ctx: APIContext<T.DocumentsUpdateReq>) => {
const { transaction } = ctx.state;
const { id, apiVersion, insightsEnabled, publish, collectionId, ...input } = const { id, apiVersion, insightsEnabled, publish, collectionId, ...input } =
ctx.input.body; ctx.input.body;
const editorVersion = ctx.headers["x-editor-version"] as string | undefined; const editorVersion = ctx.headers["x-editor-version"] as string | undefined;
@@ -922,28 +924,24 @@ router.post(
authorize(user, "createDocument", collection); authorize(user, "createDocument", collection);
} }
collection = await sequelize.transaction(async (transaction) => { await documentUpdater({
await documentUpdater({ document,
document, user,
user, ...input,
...input, publish,
publish, collectionId,
collectionId, insightsEnabled,
insightsEnabled, editorVersion,
editorVersion, transaction,
transaction, ip: ctx.request.ip,
ip: ctx.request.ip,
});
if (!document.collectionId) {
return null;
}
return await Collection.scope({
method: ["withMembership", user.id],
}).findByPk(document.collectionId, { transaction });
}); });
collection = document.collectionId
? await Collection.scope({
method: ["withMembership", user.id],
}).findByPk(document.collectionId, { transaction })
: null;
document.updatedBy = user; document.updatedBy = user;
document.collection = collection; document.collection = collection;
@@ -966,7 +964,9 @@ router.post(
"documents.move", "documents.move",
auth(), auth(),
validate(T.DocumentsMoveSchema), validate(T.DocumentsMoveSchema),
transaction(),
async (ctx: APIContext<T.DocumentsMoveReq>) => { async (ctx: APIContext<T.DocumentsMoveReq>) => {
const { transaction } = ctx.state;
const { id, collectionId, parentDocumentId, index } = ctx.input.body; const { id, collectionId, parentDocumentId, index } = ctx.input.body;
const { user } = ctx.state.auth; const { user } = ctx.state.auth;
const document = await Document.findByPk(id, { const document = await Document.findByPk(id, {
@@ -990,18 +990,15 @@ router.post(
} }
} }
const { documents, collections, collectionChanged } = const { documents, collections, collectionChanged } = await documentMover({
await sequelize.transaction(async (transaction) => user,
documentMover({ document,
user, collectionId,
document, parentDocumentId,
collectionId, index,
parentDocumentId, ip: ctx.request.ip,
index, transaction,
ip: ctx.request.ip, });
transaction,
})
);
ctx.body = { ctx.body = {
data: { data: {
@@ -1167,6 +1164,7 @@ router.post(
"documents.import", "documents.import",
auth(), auth(),
validate(T.DocumentsImportSchema), validate(T.DocumentsImportSchema),
transaction(),
async (ctx: APIContext<T.DocumentsImportReq>) => { async (ctx: APIContext<T.DocumentsImportReq>) => {
if (!ctx.is("multipart/form-data")) { if (!ctx.is("multipart/form-data")) {
throw InvalidRequestError("Request type must be multipart/form-data"); throw InvalidRequestError("Request type must be multipart/form-data");
@@ -1187,6 +1185,7 @@ router.post(
); );
} }
const { transaction } = ctx.state;
const { user } = ctx.state.auth; const { user } = ctx.state.auth;
const collection = await Collection.scope({ const collection = await Collection.scope({
@@ -1213,28 +1212,26 @@ router.post(
} }
const content = await fs.readFile(file.filepath); const content = await fs.readFile(file.filepath);
const document = await sequelize.transaction(async (transaction) => { const { text, state, title } = await documentImporter({
const { text, state, title } = await documentImporter({ user,
user, fileName: file.originalFilename ?? file.newFilename,
fileName: file.originalFilename ?? file.newFilename, mimeType: file.mimetype ?? "",
mimeType: file.mimetype ?? "", content,
content, ip: ctx.request.ip,
ip: ctx.request.ip, transaction,
transaction, });
});
return documentCreator({ const document = await documentCreator({
source: "import", source: "import",
title, title,
text, text,
state, state,
publish, publish,
collectionId, collectionId,
parentDocumentId, parentDocumentId,
user, user,
ip: ctx.request.ip, ip: ctx.request.ip,
transaction, transaction,
});
}); });
document.collection = collection; document.collection = collection;
@@ -1250,6 +1247,7 @@ router.post(
"documents.create", "documents.create",
auth(), auth(),
validate(T.DocumentsCreateSchema), validate(T.DocumentsCreateSchema),
transaction(),
async (ctx: APIContext<T.DocumentsCreateReq>) => { async (ctx: APIContext<T.DocumentsCreateReq>) => {
const { const {
title = "", title = "",
@@ -1263,6 +1261,7 @@ router.post(
} = ctx.input.body; } = ctx.input.body;
const editorVersion = ctx.headers["x-editor-version"] as string | undefined; const editorVersion = ctx.headers["x-editor-version"] as string | undefined;
const { transaction } = ctx.state;
const { user } = ctx.state.auth; const { user } = ctx.state.auth;
let collection; let collection;
@@ -1302,22 +1301,20 @@ router.post(
authorize(user, "read", templateDocument); authorize(user, "read", templateDocument);
} }
const document = await sequelize.transaction(async (transaction) => const document = await documentCreator({
documentCreator({ title,
title, text,
text, publish,
publish, collectionId,
collectionId, parentDocumentId,
parentDocumentId, templateDocument,
templateDocument, template,
template, fullWidth,
fullWidth, user,
user, editorVersion,
editorVersion, ip: ctx.request.ip,
ip: ctx.request.ip, transaction,
transaction, });
})
);
document.collection = collection; document.collection = collection;

View File

@@ -3,8 +3,8 @@ import { Sequelize } from "sequelize";
import starCreator from "@server/commands/starCreator"; import starCreator from "@server/commands/starCreator";
import starDestroyer from "@server/commands/starDestroyer"; import starDestroyer from "@server/commands/starDestroyer";
import starUpdater from "@server/commands/starUpdater"; import starUpdater from "@server/commands/starUpdater";
import { sequelize } from "@server/database/sequelize";
import auth from "@server/middlewares/authentication"; import auth from "@server/middlewares/authentication";
import { transaction } from "@server/middlewares/transaction";
import validate from "@server/middlewares/validate"; import validate from "@server/middlewares/validate";
import { Document, Star, Collection } from "@server/models"; import { Document, Star, Collection } from "@server/models";
import { authorize } from "@server/policies"; import { authorize } from "@server/policies";
@@ -24,7 +24,9 @@ router.post(
"stars.create", "stars.create",
auth(), auth(),
validate(T.StarsCreateSchema), validate(T.StarsCreateSchema),
transaction(),
async (ctx: APIContext<T.StarsCreateReq>) => { async (ctx: APIContext<T.StarsCreateReq>) => {
const { transaction } = ctx.state;
const { documentId, collectionId, index } = ctx.input.body; const { documentId, collectionId, index } = ctx.input.body;
const { user } = ctx.state.auth; const { user } = ctx.state.auth;
@@ -42,16 +44,15 @@ router.post(
authorize(user, "star", collection); authorize(user, "star", collection);
} }
const star = await sequelize.transaction(async (transaction) => const star = await starCreator({
starCreator({ user,
user, documentId,
documentId, collectionId,
collectionId, ip: ctx.request.ip,
ip: ctx.request.ip, index,
index, transaction,
transaction, });
})
);
ctx.body = { ctx.body = {
data: presentStar(star), data: presentStar(star),
policies: presentPolicies(user, [star]), policies: presentPolicies(user, [star]),

View File

@@ -2,7 +2,6 @@ import invariant from "invariant";
import Router from "koa-router"; import Router from "koa-router";
import teamCreator from "@server/commands/teamCreator"; import teamCreator from "@server/commands/teamCreator";
import teamUpdater from "@server/commands/teamUpdater"; import teamUpdater from "@server/commands/teamUpdater";
import { sequelize } from "@server/database/sequelize";
import auth from "@server/middlewares/authentication"; import auth from "@server/middlewares/authentication";
import { rateLimiter } from "@server/middlewares/rateLimiter"; import { rateLimiter } from "@server/middlewares/rateLimiter";
import { transaction } from "@server/middlewares/transaction"; import { transaction } from "@server/middlewares/transaction";
@@ -49,7 +48,9 @@ router.post(
"teams.create", "teams.create",
rateLimiter(RateLimiterStrategy.FivePerHour), rateLimiter(RateLimiterStrategy.FivePerHour),
auth(), auth(),
transaction(),
async (ctx: APIContext) => { async (ctx: APIContext) => {
const { transaction } = ctx.state;
const { user } = ctx.state.auth; const { user } = ctx.state.auth;
const { name } = ctx.request.body; const { name } = ctx.request.body;
@@ -73,42 +74,38 @@ router.post(
"Team must have at least one authentication provider" "Team must have at least one authentication provider"
); );
const [team, newUser] = await sequelize.transaction(async (transaction) => { const team = await teamCreator({
const team = await teamCreator({ name,
name, subdomain: name,
subdomain: name, authenticationProviders,
authenticationProviders, ip: ctx.ip,
ip: ctx.ip, transaction,
transaction,
});
const newUser = await User.create(
{
teamId: team.id,
name: user.name,
email: user.email,
isAdmin: true,
},
{ transaction }
);
await Event.create(
{
name: "users.create",
actorId: user.id,
userId: newUser.id,
teamId: newUser.teamId,
data: {
name: newUser.name,
},
ip: ctx.ip,
},
{ transaction }
);
return [team, newUser];
}); });
const newUser = await User.create(
{
teamId: team.id,
name: user.name,
email: user.email,
isAdmin: true,
},
{ transaction }
);
await Event.create(
{
name: "users.create",
actorId: user.id,
userId: newUser.id,
teamId: newUser.teamId,
data: {
name: newUser.name,
},
ip: ctx.ip,
},
{ transaction }
);
ctx.body = { ctx.body = {
success: true, success: true,
data: { data: {