mirror of
https://github.com/usatiuk/photos.git
synced 2025-10-28 23:37:48 +01:00
some updates
This commit is contained in:
8124
backend/package-lock.json
generated
8124
backend/package-lock.json
generated
File diff suppressed because it is too large
Load Diff
@@ -14,7 +14,7 @@
|
||||
},
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@koa/cors": "^4.0.0",
|
||||
"@koa/cors": "^5",
|
||||
"@koa/router": "^12.0.0",
|
||||
"bcrypt": "^5.1.0",
|
||||
"class-validator": "^0.14.0",
|
||||
@@ -43,16 +43,17 @@
|
||||
"@types/deasync": "^0.1.2",
|
||||
"@types/eslint": "^8.44.1",
|
||||
"@types/eslint-config-prettier": "^6.11.0",
|
||||
"@types/eslint-plugin-mocha": "^10.4.0",
|
||||
"@types/eslint-plugin-prettier": "^3.1.0",
|
||||
"@types/hasha": "^3.0.1",
|
||||
"@types/jsonwebtoken": "^9.0.2",
|
||||
"@types/koa": "^2.13.7",
|
||||
"@types/koa__cors": "^4.0.0",
|
||||
"@types/koa__router": "^12.0.0",
|
||||
"@types/koa-logger": "^3.1.2",
|
||||
"@types/koa-send": "^4.1.3",
|
||||
"@types/koa-sslify": "^4.0.3",
|
||||
"@types/koa-static": "^4.0.2",
|
||||
"@types/koa__cors": "^4.0.0",
|
||||
"@types/koa__router": "^12.0.0",
|
||||
"@types/mime-types": "^2.1.1",
|
||||
"@types/mocha": "^10.0.1",
|
||||
"@types/mysql": "^2.15.21",
|
||||
|
||||
@@ -52,7 +52,7 @@ export async function getConfigValue(key: ConfigKey): Promise<string> {
|
||||
}
|
||||
|
||||
try {
|
||||
const pair = await Config.findOneOrFail({ key });
|
||||
const pair = await Config.findOneOrFail({ key }, {});
|
||||
return pair.value;
|
||||
} catch (e) {
|
||||
return defaultValues[key];
|
||||
@@ -67,7 +67,7 @@ export async function setConfigValue(
|
||||
throw new Error(`${key} is not valid config key`);
|
||||
}
|
||||
|
||||
let pair = await Config.findOne({ key });
|
||||
let pair = await Config.findOne({ key }, {});
|
||||
if (!pair) {
|
||||
pair = new Config(key, val);
|
||||
} else {
|
||||
|
||||
@@ -1,26 +1,26 @@
|
||||
import * as Router from "@koa/router";
|
||||
import { Photo } from "~entity/Photo";
|
||||
import {
|
||||
TPhotoReqJSON,
|
||||
TPhotosNewRespBody,
|
||||
TPhotoByIDDeleteRespBody,
|
||||
TPhotosUploadRespBody,
|
||||
TPhotosListRespBody,
|
||||
TPhotosByIDGetRespBody,
|
||||
TPhotosDeleteRespBody,
|
||||
PhotoJSON,
|
||||
PhotosDeleteBody,
|
||||
PhotosListPagination,
|
||||
PhotosNewPostBody,
|
||||
PhotoJSON,
|
||||
TPhotoByIDDeleteRespBody,
|
||||
TPhotoReqJSON,
|
||||
TPhotosByIDGetRespBody,
|
||||
TPhotosDeleteRespBody,
|
||||
TPhotosGetShowTokenByIDRespBody,
|
||||
PhotosDeleteBody,
|
||||
TPhotosListRespBody,
|
||||
TPhotosNewRespBody,
|
||||
TPhotosUploadRespBody,
|
||||
} from "~/shared/types";
|
||||
import send = require("koa-send");
|
||||
import { getHash, getSize } from "~util";
|
||||
import * as jwt from "jsonwebtoken";
|
||||
import { config } from "~config";
|
||||
import { ValidationError } from "class-validator";
|
||||
import { In } from "typeorm";
|
||||
import { IAppContext, IAppState } from "~app";
|
||||
import send = require("koa-send");
|
||||
|
||||
export const photosRouter = new Router<IAppState, IAppContext>();
|
||||
|
||||
@@ -44,7 +44,7 @@ photosRouter.post("/photos/new", async (ctx: ContextType) => {
|
||||
await photo.save();
|
||||
} catch (e) {
|
||||
if (e.code === "ER_DUP_ENTRY") {
|
||||
const photo = await Photo.findOne({ hash, size, user });
|
||||
const photo = await Photo.findOne({ hash, size, user }, {});
|
||||
if (!photo) {
|
||||
ctx.throw(404);
|
||||
}
|
||||
@@ -85,7 +85,7 @@ photosRouter.post("/photos/upload/:id", async (ctx: ContextType) => {
|
||||
}
|
||||
|
||||
const { user } = ctx.state;
|
||||
const photo = await Photo.findOne({ id: parseInt(id), user });
|
||||
const photo = await Photo.findOne({ id: parseInt(id), user }, {});
|
||||
if (!photo) {
|
||||
ctx.throw(404);
|
||||
}
|
||||
@@ -131,47 +131,47 @@ photosRouter.post("/photos/upload/:id", async (ctx: ContextType) => {
|
||||
});
|
||||
|
||||
/**
|
||||
export interface TPhotosByIDPatchBody {
|
||||
}
|
||||
export type TPhotosByIDPatchRespBody = IAPIResponse<TPhotoReqJSON>;
|
||||
photosRouter.patch("/photos/byID/:id", async (ctx: ContextType) => {
|
||||
if (!ctx.state.user) {
|
||||
ctx.throw(401);
|
||||
return;
|
||||
}
|
||||
|
||||
const { user } = ctx.state;
|
||||
const { id } = ctx.params as {
|
||||
id: number | undefined;
|
||||
};
|
||||
|
||||
if (!id) {
|
||||
ctx.throw(400);
|
||||
return;
|
||||
}
|
||||
|
||||
const photo = await Photo.findOne({ id, user });
|
||||
|
||||
if (!photo) {
|
||||
ctx.throw(404);
|
||||
return;
|
||||
}
|
||||
|
||||
// TODO: Some actual editing
|
||||
|
||||
try {
|
||||
photo.editedAt = new Date();
|
||||
await photo.save();
|
||||
} catch (e) {
|
||||
ctx.throw(400);
|
||||
}
|
||||
|
||||
ctx.body = {
|
||||
error: false,
|
||||
data: photo.toReqJSON(),
|
||||
};
|
||||
});
|
||||
*/
|
||||
export interface TPhotosByIDPatchBody {
|
||||
}
|
||||
export type TPhotosByIDPatchRespBody = IAPIResponse<TPhotoReqJSON>;
|
||||
photosRouter.patch("/photos/byID/:id", async (ctx: ContextType) => {
|
||||
if (!ctx.state.user) {
|
||||
ctx.throw(401);
|
||||
return;
|
||||
}
|
||||
|
||||
const { user } = ctx.state;
|
||||
const { id } = ctx.params as {
|
||||
id: number | undefined;
|
||||
};
|
||||
|
||||
if (!id) {
|
||||
ctx.throw(400);
|
||||
return;
|
||||
}
|
||||
|
||||
const photo = await Photo.findOne({ id, user },{});
|
||||
|
||||
if (!photo) {
|
||||
ctx.throw(404);
|
||||
return;
|
||||
}
|
||||
|
||||
// TODO: Some actual editing
|
||||
|
||||
try {
|
||||
photo.editedAt = new Date();
|
||||
await photo.save();
|
||||
} catch (e) {
|
||||
ctx.throw(400);
|
||||
}
|
||||
|
||||
ctx.body = {
|
||||
error: false,
|
||||
data: photo.toReqJSON(),
|
||||
};
|
||||
});
|
||||
*/
|
||||
|
||||
photosRouter.get("/photos/list", async (ctx: ContextType) => {
|
||||
if (!ctx.state.user) {
|
||||
@@ -229,7 +229,7 @@ photosRouter.get("/photos/byID/:id", async (ctx: ContextType) => {
|
||||
|
||||
const { user } = ctx.state;
|
||||
|
||||
const photo = await Photo.findOne({ id: parseInt(id), user });
|
||||
const photo = await Photo.findOne({ id: parseInt(id), user }, {});
|
||||
|
||||
if (!photo) {
|
||||
ctx.throw(404);
|
||||
@@ -260,10 +260,13 @@ photosRouter.get("/photos/showByID/:id/:token", async (ctx: ContextType) => {
|
||||
const photoReqJSON = PhotoJSON.parse(jwt.decode(token));
|
||||
const { user } = photoReqJSON;
|
||||
|
||||
const photo = await Photo.findOne({
|
||||
id: parseInt(id),
|
||||
user: { id: user },
|
||||
});
|
||||
const photo = await Photo.findOne(
|
||||
{
|
||||
id: parseInt(id),
|
||||
user: { id: user },
|
||||
},
|
||||
{},
|
||||
);
|
||||
|
||||
if (!photo) {
|
||||
ctx.throw(404);
|
||||
@@ -296,7 +299,7 @@ photosRouter.get("/photos/showByID/:id", async (ctx: ContextType) => {
|
||||
|
||||
const { user } = ctx.state;
|
||||
|
||||
const photo = await Photo.findOne({ id: parseInt(id), user });
|
||||
const photo = await Photo.findOne({ id: parseInt(id), user }, {});
|
||||
|
||||
if (!photo) {
|
||||
ctx.throw(404);
|
||||
@@ -329,7 +332,7 @@ photosRouter.get("/photos/getShowByIDToken/:id", async (ctx: ContextType) => {
|
||||
|
||||
const { user } = ctx.state;
|
||||
|
||||
const photo = await Photo.findOne({ id: parseInt(id), user });
|
||||
const photo = await Photo.findOne({ id: parseInt(id), user }, {});
|
||||
if (!photo) {
|
||||
ctx.throw(404);
|
||||
}
|
||||
@@ -354,7 +357,7 @@ photosRouter.delete("/photos/byID/:id", async (ctx: ContextType) => {
|
||||
|
||||
const { user } = ctx.state;
|
||||
|
||||
const photo = await Photo.findOne({ id: parseInt(id), user });
|
||||
const photo = await Photo.findOne({ id: parseInt(id), user }, {});
|
||||
|
||||
if (!photo) {
|
||||
ctx.throw(404);
|
||||
|
||||
@@ -1,18 +1,14 @@
|
||||
import * as Router from "@koa/router";
|
||||
import { getConfigValue, ConfigKey } from "~entity/Config";
|
||||
import { ConfigKey, getConfigValue } from "~entity/Config";
|
||||
import { User } from "~entity/User";
|
||||
import {
|
||||
TUserJWT,
|
||||
TUserGetRespBody,
|
||||
TUserEditRespBody,
|
||||
TUserSignupBody,
|
||||
TUserSignupRespBody,
|
||||
TUserGetRespBody,
|
||||
TUserLoginRespBody,
|
||||
TUserEditBody,
|
||||
TUserLoginBody,
|
||||
TUserSignupRespBody,
|
||||
UserEditBody,
|
||||
UserLoginBody,
|
||||
UserSignupBody,
|
||||
UserEditBody,
|
||||
} from "~/shared/types";
|
||||
import { IAppContext, IAppState } from "~app";
|
||||
|
||||
@@ -28,7 +24,7 @@ userRouter.get("/users/user", async (ctx: ContextType) => {
|
||||
}
|
||||
|
||||
const jwt = ctx.state.user;
|
||||
const user = await User.findOne(jwt.id);
|
||||
const user = await User.findOne(jwt.id, {});
|
||||
|
||||
if (!user) {
|
||||
ctx.throw(401);
|
||||
@@ -45,7 +41,7 @@ userRouter.post("/users/login", async (ctx: ContextType) => {
|
||||
}
|
||||
const { username, password } = UserLoginBody.parse(request.body);
|
||||
|
||||
const user = await User.findOne({ username });
|
||||
const user = await User.findOne({ username }, {});
|
||||
if (!user || !(await user.verifyPassword(password))) {
|
||||
ctx.throw(404, "User not found");
|
||||
}
|
||||
@@ -95,7 +91,7 @@ userRouter.post("/users/edit", async (ctx: ContextType) => {
|
||||
}
|
||||
|
||||
const jwt = ctx.state.user;
|
||||
const user = await User.findOne(jwt.id);
|
||||
const user = await User.findOne(jwt.id, {});
|
||||
const request = ctx.request;
|
||||
|
||||
if (!user) {
|
||||
|
||||
@@ -86,7 +86,9 @@ describe("photos", function () {
|
||||
Authorization: `Bearer ${seed.user2.toJWT()}`,
|
||||
})
|
||||
.expect(200);
|
||||
expect(parseInt(response.get("content-length"))).to.equal(dogFileSize);
|
||||
expect(parseInt(response.get("content-length") ?? "")).to.equal(
|
||||
dogFileSize,
|
||||
);
|
||||
});
|
||||
|
||||
it("should delete a photo after file has been deleted", async function () {
|
||||
@@ -96,7 +98,9 @@ describe("photos", function () {
|
||||
Authorization: `Bearer ${seed.user2.toJWT()}`,
|
||||
})
|
||||
.expect(200);
|
||||
expect(parseInt(response.get("content-length"))).to.equal(dogFileSize);
|
||||
expect(parseInt(response.get("content-length") ?? "")).to.equal(
|
||||
dogFileSize,
|
||||
);
|
||||
|
||||
await fs.unlink(await seed.dogPhoto.getReadyPath("original"));
|
||||
await request(callback)
|
||||
@@ -119,7 +123,7 @@ describe("photos", function () {
|
||||
const dogSmallThumbSize = (
|
||||
await fs.stat(seed.dogPhoto.getThumbPath("512"))
|
||||
).size;
|
||||
expect(parseInt(response.get("content-length"))).to.equal(
|
||||
expect(parseInt(response.get("content-length") ?? "")).to.equal(
|
||||
dogSmallThumbSize,
|
||||
);
|
||||
|
||||
@@ -143,7 +147,7 @@ describe("photos", function () {
|
||||
Authorization: `Bearer ${seed.user2.toJWT()}`,
|
||||
})
|
||||
.expect(200);
|
||||
expect(parseInt(response.get("content-length"))).to.be.lessThan(
|
||||
expect(parseInt(response.get("content-length") ?? "")).to.be.lessThan(
|
||||
dogFileSize,
|
||||
);
|
||||
});
|
||||
@@ -158,7 +162,7 @@ describe("photos", function () {
|
||||
const dogSmallThumbSize = (
|
||||
await fs.stat(seed.dogPhoto.getThumbPath("512"))
|
||||
).size;
|
||||
expect(parseInt(response.get("content-length"))).to.equal(
|
||||
expect(parseInt(response.get("content-length") ?? "")).to.equal(
|
||||
dogSmallThumbSize,
|
||||
);
|
||||
|
||||
@@ -172,7 +176,7 @@ describe("photos", function () {
|
||||
const dogSmallThumbSize2 = (
|
||||
await fs.stat(seed.dogPhoto.getThumbPath("512"))
|
||||
).size;
|
||||
expect(parseInt(response.get("content-length"))).to.equal(
|
||||
expect(parseInt(response.get("content-length") ?? "")).to.equal(
|
||||
dogSmallThumbSize2,
|
||||
);
|
||||
});
|
||||
@@ -198,7 +202,7 @@ describe("photos", function () {
|
||||
const listAnyResp = await request(callback)
|
||||
.get(`/photos/showByID/${photos[0].id}/${photos[0].accessToken}`)
|
||||
.expect(200);
|
||||
expect(parseInt(listAnyResp.get("content-length"))).to.be.oneOf([
|
||||
expect(parseInt(listAnyResp.get("content-length") ?? "")).to.be.oneOf([
|
||||
dogFileSize,
|
||||
catFileSize,
|
||||
]);
|
||||
@@ -216,7 +220,9 @@ describe("photos", function () {
|
||||
const response = await request(callback)
|
||||
.get(`/photos/showByID/${seed.dogPhoto.id}/${token}`)
|
||||
.expect(200);
|
||||
expect(parseInt(response.get("content-length"))).to.equal(dogFileSize);
|
||||
expect(parseInt(response.get("content-length") ?? "")).to.equal(
|
||||
dogFileSize,
|
||||
);
|
||||
|
||||
const tokenSelfSigned = jwt.sign(
|
||||
await seed.dogPhoto.toReqJSON(),
|
||||
@@ -229,7 +235,7 @@ describe("photos", function () {
|
||||
const responseSS = await request(callback)
|
||||
.get(`/photos/showByID/${seed.dogPhoto.id}/${tokenSelfSigned}`)
|
||||
.expect(200);
|
||||
expect(parseInt(responseSS.get("content-length"))).to.equal(
|
||||
expect(parseInt(responseSS.get("content-length") ?? "")).to.equal(
|
||||
dogFileSize,
|
||||
);
|
||||
});
|
||||
@@ -312,7 +318,9 @@ describe("photos", function () {
|
||||
})
|
||||
.expect(200);
|
||||
|
||||
expect(parseInt(showResp.get("content-length"))).to.equal(dogFileSize);
|
||||
expect(parseInt(showResp.get("content-length") ?? "")).to.equal(
|
||||
dogFileSize,
|
||||
);
|
||||
});
|
||||
|
||||
it("should create, upload and show a png file", async function () {
|
||||
@@ -370,7 +378,9 @@ describe("photos", function () {
|
||||
})
|
||||
.expect(200);
|
||||
|
||||
expect(parseInt(showResp.get("content-length"))).to.equal(pngFileSize);
|
||||
expect(parseInt(showResp.get("content-length") ?? "")).to.equal(
|
||||
pngFileSize,
|
||||
);
|
||||
});
|
||||
|
||||
it("should not create a photo twice", async function () {
|
||||
@@ -464,7 +474,9 @@ describe("photos", function () {
|
||||
})
|
||||
.expect(200);
|
||||
|
||||
expect(parseInt(showResp.get("content-length"))).to.equal(dogFileSize);
|
||||
expect(parseInt(showResp.get("content-length") ?? "")).to.equal(
|
||||
dogFileSize,
|
||||
);
|
||||
});
|
||||
|
||||
it("should not upload a wrong photo", async function () {
|
||||
|
||||
Reference in New Issue
Block a user