client/server: lint
This commit is contained in:
parent
6afc4c915e
commit
85ae8173bb
20 changed files with 323 additions and 328 deletions
|
@ -77,7 +77,7 @@ const Admin = () => {
|
||||||
</tr>
|
</tr>
|
||||||
</thead>
|
</thead>
|
||||||
<tbody>
|
<tbody>
|
||||||
{posts?.map((post, i) => (
|
{posts?.map((post) => (
|
||||||
<tr key={post.id}>
|
<tr key={post.id}>
|
||||||
<td><PostModal id={post.id} /></td>
|
<td><PostModal id={post.id} /></td>
|
||||||
<td>{post.visibility}</td>
|
<td>{post.visibility}</td>
|
||||||
|
|
|
@ -53,10 +53,9 @@ export const allowedFileNames = [
|
||||||
".fish_prompt",
|
".fish_prompt",
|
||||||
".zshrc",
|
".zshrc",
|
||||||
".zsh",
|
".zsh",
|
||||||
".zprofile",
|
".zprofile"
|
||||||
]
|
]
|
||||||
|
|
||||||
|
|
||||||
export const codeFileExtensions = [
|
export const codeFileExtensions = [
|
||||||
"awk",
|
"awk",
|
||||||
"bat",
|
"bat",
|
||||||
|
@ -120,5 +119,5 @@ export const allowedFileExtensions = [
|
||||||
"txt",
|
"txt",
|
||||||
"webmanifest",
|
"webmanifest",
|
||||||
"log",
|
"log",
|
||||||
...codeFileExtensions,
|
...codeFileExtensions
|
||||||
]
|
]
|
||||||
|
|
|
@ -1,41 +1,43 @@
|
||||||
import { User } from "@lib/types";
|
import { User } from "@lib/types"
|
||||||
import Cookies from "js-cookie";
|
import Cookies from "js-cookie"
|
||||||
import { useRouter } from "next/router";
|
import { useRouter } from "next/router"
|
||||||
import { useEffect, useMemo, useState } from "react";
|
import { useEffect, useMemo, useState } from "react"
|
||||||
|
|
||||||
const useUserData = () => {
|
const useUserData = () => {
|
||||||
const [authToken, setAuthToken] = useState<string>(Cookies.get("drift-token") || '');
|
const [authToken, setAuthToken] = useState<string>(
|
||||||
const [user, setUser] = useState<User>();
|
Cookies.get("drift-token") || ""
|
||||||
const router = useRouter()
|
)
|
||||||
useEffect(() => {
|
const [user, setUser] = useState<User>()
|
||||||
const token = Cookies.get("drift-token")
|
const router = useRouter()
|
||||||
if (token) {
|
useEffect(() => {
|
||||||
setAuthToken(token)
|
const token = Cookies.get("drift-token")
|
||||||
}
|
if (token) {
|
||||||
}, [setAuthToken])
|
setAuthToken(token)
|
||||||
|
}
|
||||||
|
}, [setAuthToken])
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (authToken) {
|
if (authToken) {
|
||||||
const fetchUser = async () => {
|
const fetchUser = async () => {
|
||||||
const response = await fetch(`/server-api/users/self`, {
|
const response = await fetch(`/server-api/users/self`, {
|
||||||
headers: {
|
headers: {
|
||||||
"Authorization": `Bearer ${authToken}`
|
Authorization: `Bearer ${authToken}`
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
if (response.ok) {
|
if (response.ok) {
|
||||||
const user = await response.json()
|
const user = await response.json()
|
||||||
setUser(user)
|
setUser(user)
|
||||||
} else {
|
} else {
|
||||||
Cookies.remove("drift-token")
|
Cookies.remove("drift-token")
|
||||||
setAuthToken("")
|
setAuthToken("")
|
||||||
router.push("/")
|
router.push("/")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
fetchUser()
|
fetchUser()
|
||||||
}
|
}
|
||||||
}, [authToken, router])
|
}, [authToken, router])
|
||||||
|
|
||||||
return user;
|
return user
|
||||||
}
|
}
|
||||||
|
|
||||||
export default useUserData
|
export default useUserData
|
||||||
|
|
|
@ -1,14 +1,11 @@
|
||||||
import databasePath from "@lib/get-database-path";
|
import databasePath from "@lib/get-database-path"
|
||||||
import { Sequelize } from "sequelize-typescript"
|
import { Sequelize } from "sequelize-typescript"
|
||||||
import { SequelizeStorage, Umzug } from "umzug"
|
import { SequelizeStorage, Umzug } from "umzug"
|
||||||
|
|
||||||
export const sequelize = new Sequelize({
|
export const sequelize = new Sequelize({
|
||||||
dialect: "sqlite",
|
dialect: "sqlite",
|
||||||
database: "drift",
|
database: "drift",
|
||||||
storage:
|
storage: process.env.MEMORY_DB === "true" ? ":memory:" : databasePath,
|
||||||
process.env.MEMORY_DB === "true"
|
|
||||||
? ":memory:"
|
|
||||||
: databasePath,
|
|
||||||
models: [__dirname + "/lib/models"],
|
models: [__dirname + "/lib/models"],
|
||||||
logging: true
|
logging: true
|
||||||
})
|
})
|
||||||
|
@ -20,24 +17,28 @@ if (process.env.MEMORY_DB !== "true") {
|
||||||
}
|
}
|
||||||
|
|
||||||
const umzug = new Umzug({
|
const umzug = new Umzug({
|
||||||
migrations: { glob: process.env.NODE_ENV === "production" ? __dirname + "/migrations/*.js" : __dirname + "/migrations/*.ts" },
|
migrations: {
|
||||||
|
glob:
|
||||||
|
process.env.NODE_ENV === "production"
|
||||||
|
? __dirname + "/migrations/*.js"
|
||||||
|
: __dirname + "/migrations/*.ts"
|
||||||
|
},
|
||||||
context: sequelize.getQueryInterface(),
|
context: sequelize.getQueryInterface(),
|
||||||
storage: new SequelizeStorage({ sequelize }),
|
storage: new SequelizeStorage({ sequelize }),
|
||||||
logger: console
|
logger: console
|
||||||
})
|
})
|
||||||
|
|
||||||
export type Migration = typeof umzug._types.migration
|
export type Migration = typeof umzug._types.migration
|
||||||
|
;(async () => {
|
||||||
; (async () => {
|
// Checks migrations and run them if they are not already applied. To keep
|
||||||
// Checks migrations and run them if they are not already applied. To keep
|
// track of the executed migrations, a table (and sequelize model) called SequelizeMeta
|
||||||
// track of the executed migrations, a table (and sequelize model) called SequelizeMeta
|
// will be automatically created (if it doesn't exist already) and parsed.
|
||||||
// will be automatically created (if it doesn't exist already) and parsed.
|
console.log("Checking migrations...")
|
||||||
console.log("Checking migrations...")
|
const migrations = await umzug.up()
|
||||||
const migrations = await umzug.up()
|
if (migrations.length > 0) {
|
||||||
if (migrations.length > 0) {
|
console.log("Migrations applied:")
|
||||||
console.log("Migrations applied:")
|
console.log(migrations)
|
||||||
console.log(migrations)
|
} else {
|
||||||
} else {
|
console.log("No migrations applied.")
|
||||||
console.log("No migrations applied.")
|
}
|
||||||
}
|
})()
|
||||||
})()
|
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
export default {
|
export default {
|
||||||
port: process.env.PORT || 3000,
|
port: process.env.PORT || 3000,
|
||||||
jwt_secret: process.env.JWT_SECRET || "myjwtsecret",
|
jwt_secret: process.env.JWT_SECRET || "myjwtsecret",
|
||||||
drift_home: process.env.DRIFT_HOME || "~/.drift",
|
drift_home: process.env.DRIFT_HOME || "~/.drift"
|
||||||
}
|
}
|
||||||
|
|
|
@ -6,11 +6,12 @@ import config from "./config"
|
||||||
// Expand ~ into the current user home dir.
|
// Expand ~ into the current user home dir.
|
||||||
// This does *not* support `~other_user/tmp` => `/home/other_user/tmp`.
|
// This does *not* support `~other_user/tmp` => `/home/other_user/tmp`.
|
||||||
function getDatabasePath() {
|
function getDatabasePath() {
|
||||||
const fileName = "drift.sqlite"
|
const fileName = "drift.sqlite"
|
||||||
const databasePath = `${config.drift_home}/${fileName}` || `~/.drift/${fileName}`
|
const databasePath =
|
||||||
|
`${config.drift_home}/${fileName}` || `~/.drift/${fileName}`
|
||||||
|
|
||||||
const home = os.homedir().replace("$", "$$$$");
|
const home = os.homedir().replace("$", "$$$$")
|
||||||
return path.resolve(databasePath.replace(/^~($|\/|\\)/, home + "$1"));
|
return path.resolve(databasePath.replace(/^~($|\/|\\)/, home + "$1"))
|
||||||
}
|
}
|
||||||
|
|
||||||
export default getDatabasePath()
|
export default getDatabasePath()
|
||||||
|
|
|
@ -25,11 +25,11 @@ export default function authenticateToken(
|
||||||
if (err) return res.sendStatus(403)
|
if (err) return res.sendStatus(403)
|
||||||
const userObj = await UserModel.findByPk(user.id, {
|
const userObj = await UserModel.findByPk(user.id, {
|
||||||
attributes: {
|
attributes: {
|
||||||
exclude: ["password"],
|
exclude: ["password"]
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
if (!userObj || userObj.role !== 'admin') {
|
if (!userObj || userObj.role !== "admin") {
|
||||||
return res.sendStatus(403)
|
return res.sendStatus(403)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -28,11 +28,9 @@ import { User } from "./User"
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
}))
|
}))
|
||||||
|
|
||||||
@Table({
|
@Table({
|
||||||
tableName: "files",
|
tableName: "files"
|
||||||
})
|
})
|
||||||
|
|
||||||
export class File extends Model {
|
export class File extends Model {
|
||||||
@IsUUID(4)
|
@IsUUID(4)
|
||||||
@PrimaryKey
|
@PrimaryKey
|
||||||
|
|
|
@ -38,11 +38,9 @@ import { File } from "./File"
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
}))
|
}))
|
||||||
@Table(
|
@Table({
|
||||||
{
|
tableName: "posts"
|
||||||
tableName: "posts",
|
})
|
||||||
}
|
|
||||||
)
|
|
||||||
export class Post extends Model {
|
export class Post extends Model {
|
||||||
@IsUUID(4)
|
@IsUUID(4)
|
||||||
@PrimaryKey
|
@PrimaryKey
|
||||||
|
|
|
@ -12,9 +12,8 @@ import { Post } from "./Post"
|
||||||
import { User } from "./User"
|
import { User } from "./User"
|
||||||
|
|
||||||
@Table({
|
@Table({
|
||||||
tableName: "post_authors",
|
tableName: "post_authors"
|
||||||
})
|
})
|
||||||
|
|
||||||
export class PostAuthor extends Model {
|
export class PostAuthor extends Model {
|
||||||
@IsUUID(4)
|
@IsUUID(4)
|
||||||
@PrimaryKey
|
@PrimaryKey
|
||||||
|
|
|
@ -30,9 +30,8 @@ import { PostAuthor } from "./PostAuthor"
|
||||||
}
|
}
|
||||||
}))
|
}))
|
||||||
@Table({
|
@Table({
|
||||||
tableName: "users",
|
tableName: "users"
|
||||||
})
|
})
|
||||||
|
|
||||||
export class User extends Model {
|
export class User extends Model {
|
||||||
@IsUUID(4)
|
@IsUUID(4)
|
||||||
@PrimaryKey
|
@PrimaryKey
|
||||||
|
|
|
@ -3,29 +3,29 @@ import { DataTypes } from "sequelize"
|
||||||
import type { Migration } from "../database"
|
import type { Migration } from "../database"
|
||||||
|
|
||||||
export const up: Migration = async ({ context: queryInterface }) =>
|
export const up: Migration = async ({ context: queryInterface }) =>
|
||||||
queryInterface.createTable("users", {
|
queryInterface.createTable("users", {
|
||||||
id: {
|
id: {
|
||||||
type: DataTypes.UUID,
|
type: DataTypes.UUID,
|
||||||
defaultValue: DataTypes.UUIDV4,
|
defaultValue: DataTypes.UUIDV4,
|
||||||
primaryKey: true,
|
primaryKey: true,
|
||||||
unique: true
|
unique: true
|
||||||
},
|
},
|
||||||
username: {
|
username: {
|
||||||
type: DataTypes.STRING,
|
type: DataTypes.STRING
|
||||||
},
|
},
|
||||||
password: {
|
password: {
|
||||||
type: DataTypes.STRING,
|
type: DataTypes.STRING
|
||||||
},
|
},
|
||||||
createdAt: {
|
createdAt: {
|
||||||
type: DataTypes.DATE,
|
type: DataTypes.DATE
|
||||||
},
|
},
|
||||||
updatedAt: {
|
updatedAt: {
|
||||||
type: DataTypes.DATE,
|
type: DataTypes.DATE
|
||||||
},
|
},
|
||||||
deletedAt: {
|
deletedAt: {
|
||||||
type: DataTypes.DATE,
|
type: DataTypes.DATE
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
export const down: Migration = async ({ context: queryInterface }) =>
|
export const down: Migration = async ({ context: queryInterface }) =>
|
||||||
queryInterface.dropTable("users")
|
queryInterface.dropTable("users")
|
||||||
|
|
|
@ -3,10 +3,10 @@ import { DataTypes } from "sequelize"
|
||||||
import type { Migration } from "../database"
|
import type { Migration } from "../database"
|
||||||
|
|
||||||
export const up: Migration = async ({ context: queryInterface }) =>
|
export const up: Migration = async ({ context: queryInterface }) =>
|
||||||
queryInterface.addColumn("users", "role", {
|
queryInterface.addColumn("users", "role", {
|
||||||
type: DataTypes.STRING,
|
type: DataTypes.STRING,
|
||||||
defaultValue: "user"
|
defaultValue: "user"
|
||||||
})
|
})
|
||||||
|
|
||||||
export const down: Migration = async ({ context: queryInterface }) =>
|
export const down: Migration = async ({ context: queryInterface }) =>
|
||||||
queryInterface.removeColumn("users", "role")
|
queryInterface.removeColumn("users", "role")
|
||||||
|
|
|
@ -3,32 +3,32 @@ import { DataTypes } from "sequelize"
|
||||||
import type { Migration } from "../database"
|
import type { Migration } from "../database"
|
||||||
|
|
||||||
export const up: Migration = async ({ context: queryInterface }) =>
|
export const up: Migration = async ({ context: queryInterface }) =>
|
||||||
queryInterface.createTable("posts", {
|
queryInterface.createTable("posts", {
|
||||||
id: {
|
id: {
|
||||||
type: DataTypes.UUID,
|
type: DataTypes.UUID,
|
||||||
defaultValue: DataTypes.UUIDV4,
|
defaultValue: DataTypes.UUIDV4,
|
||||||
primaryKey: true,
|
primaryKey: true,
|
||||||
unique: true
|
unique: true
|
||||||
},
|
},
|
||||||
title: {
|
title: {
|
||||||
type: DataTypes.STRING,
|
type: DataTypes.STRING
|
||||||
},
|
},
|
||||||
visibility: {
|
visibility: {
|
||||||
type: DataTypes.STRING,
|
type: DataTypes.STRING
|
||||||
},
|
},
|
||||||
password: {
|
password: {
|
||||||
type: DataTypes.STRING,
|
type: DataTypes.STRING
|
||||||
},
|
},
|
||||||
createdAt: {
|
createdAt: {
|
||||||
type: DataTypes.DATE,
|
type: DataTypes.DATE
|
||||||
},
|
},
|
||||||
updatedAt: {
|
updatedAt: {
|
||||||
type: DataTypes.DATE,
|
type: DataTypes.DATE
|
||||||
},
|
},
|
||||||
deletedAt: {
|
deletedAt: {
|
||||||
type: DataTypes.DATE,
|
type: DataTypes.DATE
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
export const down: Migration = async ({ context: queryInterface }) =>
|
export const down: Migration = async ({ context: queryInterface }) =>
|
||||||
await queryInterface.dropTable("posts")
|
await queryInterface.dropTable("posts")
|
||||||
|
|
|
@ -3,57 +3,56 @@ import { DataTypes } from "sequelize"
|
||||||
import type { Migration } from "../database"
|
import type { Migration } from "../database"
|
||||||
|
|
||||||
export const up: Migration = async ({ context: queryInterface }) =>
|
export const up: Migration = async ({ context: queryInterface }) =>
|
||||||
queryInterface.createTable("files", {
|
queryInterface.createTable("files", {
|
||||||
id: {
|
id: {
|
||||||
type: DataTypes.UUID,
|
type: DataTypes.UUID,
|
||||||
defaultValue: DataTypes.UUIDV4,
|
defaultValue: DataTypes.UUIDV4,
|
||||||
primaryKey: true,
|
primaryKey: true,
|
||||||
allowNull: false,
|
allowNull: false,
|
||||||
unique: true
|
unique: true
|
||||||
},
|
},
|
||||||
title: {
|
title: {
|
||||||
type: DataTypes.STRING,
|
type: DataTypes.STRING
|
||||||
},
|
},
|
||||||
content: {
|
content: {
|
||||||
type: DataTypes.STRING,
|
type: DataTypes.STRING
|
||||||
},
|
},
|
||||||
sha: {
|
sha: {
|
||||||
type: DataTypes.STRING,
|
type: DataTypes.STRING
|
||||||
|
},
|
||||||
},
|
html: {
|
||||||
html: {
|
type: DataTypes.STRING
|
||||||
type: DataTypes.STRING,
|
},
|
||||||
},
|
createdAt: {
|
||||||
createdAt: {
|
type: DataTypes.DATE
|
||||||
type: DataTypes.DATE,
|
},
|
||||||
},
|
updatedAt: {
|
||||||
updatedAt: {
|
type: DataTypes.DATE
|
||||||
type: DataTypes.DATE,
|
},
|
||||||
},
|
deletedAt: {
|
||||||
deletedAt: {
|
type: DataTypes.DATE
|
||||||
type: DataTypes.DATE,
|
},
|
||||||
},
|
userId: {
|
||||||
userId: {
|
type: DataTypes.UUID,
|
||||||
type: DataTypes.UUID,
|
allowNull: false,
|
||||||
allowNull: false,
|
references: {
|
||||||
references: {
|
model: "users",
|
||||||
model: "users",
|
key: "id"
|
||||||
key: "id"
|
},
|
||||||
},
|
onDelete: "SET NULL",
|
||||||
onDelete: "SET NULL",
|
onUpdate: "CASCADE"
|
||||||
onUpdate: "CASCADE"
|
},
|
||||||
},
|
postId: {
|
||||||
postId: {
|
type: DataTypes.UUID,
|
||||||
type: DataTypes.UUID,
|
allowNull: false,
|
||||||
allowNull: false,
|
references: {
|
||||||
references: {
|
model: "posts",
|
||||||
model: "posts",
|
key: "id"
|
||||||
key: "id"
|
},
|
||||||
},
|
onDelete: "SET NULL",
|
||||||
onDelete: "SET NULL",
|
onUpdate: "CASCADE"
|
||||||
onUpdate: "CASCADE"
|
}
|
||||||
}
|
})
|
||||||
})
|
|
||||||
|
|
||||||
export const down: Migration = async ({ context: queryInterface }) =>
|
export const down: Migration = async ({ context: queryInterface }) =>
|
||||||
await queryInterface.dropTable("files")
|
await queryInterface.dropTable("files")
|
||||||
|
|
|
@ -3,39 +3,39 @@ import { DataTypes } from "sequelize"
|
||||||
import type { Migration } from "../database"
|
import type { Migration } from "../database"
|
||||||
|
|
||||||
export const up: Migration = async ({ context: queryInterface }) =>
|
export const up: Migration = async ({ context: queryInterface }) =>
|
||||||
queryInterface.createTable("post_authors", {
|
queryInterface.createTable("post_authors", {
|
||||||
id: {
|
id: {
|
||||||
type: DataTypes.UUID,
|
type: DataTypes.UUID,
|
||||||
defaultValue: DataTypes.UUIDV4,
|
defaultValue: DataTypes.UUIDV4,
|
||||||
primaryKey: true,
|
primaryKey: true
|
||||||
},
|
},
|
||||||
createdAt: {
|
createdAt: {
|
||||||
type: DataTypes.DATE,
|
type: DataTypes.DATE
|
||||||
},
|
},
|
||||||
updatedAt: {
|
updatedAt: {
|
||||||
type: DataTypes.DATE,
|
type: DataTypes.DATE
|
||||||
},
|
},
|
||||||
postId: {
|
postId: {
|
||||||
type: DataTypes.UUID,
|
type: DataTypes.UUID,
|
||||||
primaryKey: true,
|
primaryKey: true,
|
||||||
references: {
|
references: {
|
||||||
model: "posts",
|
model: "posts",
|
||||||
key: "id"
|
key: "id"
|
||||||
},
|
},
|
||||||
onDelete: "CASCADE",
|
onDelete: "CASCADE",
|
||||||
onUpdate: "CASCADE"
|
onUpdate: "CASCADE"
|
||||||
},
|
},
|
||||||
userId: {
|
userId: {
|
||||||
type: DataTypes.UUID,
|
type: DataTypes.UUID,
|
||||||
primaryKey: true,
|
primaryKey: true,
|
||||||
references: {
|
references: {
|
||||||
model: "users",
|
model: "users",
|
||||||
key: "id"
|
key: "id"
|
||||||
},
|
},
|
||||||
onDelete: "CASCADE",
|
onDelete: "CASCADE",
|
||||||
onUpdate: "CASCADE"
|
onUpdate: "CASCADE"
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
export const down: Migration = async ({ context: queryInterface }) =>
|
export const down: Migration = async ({ context: queryInterface }) =>
|
||||||
await queryInterface.dropTable("post_authors")
|
await queryInterface.dropTable("post_authors")
|
||||||
|
|
|
@ -1,115 +1,114 @@
|
||||||
import isAdmin from "@lib/middleware/is-admin";
|
import isAdmin from "@lib/middleware/is-admin"
|
||||||
import { Post } from "@lib/models/Post";
|
import { Post } from "@lib/models/Post"
|
||||||
import { User } from "@lib/models/User";
|
import { User } from "@lib/models/User"
|
||||||
import { File } from "@lib/models/File";
|
import { File } from "@lib/models/File"
|
||||||
import { Router } from "express";
|
import { Router } from "express"
|
||||||
|
|
||||||
export const admin = Router()
|
export const admin = Router()
|
||||||
|
|
||||||
admin.use(isAdmin)
|
admin.use(isAdmin)
|
||||||
|
|
||||||
admin.get("/is-admin", async (req, res) => {
|
admin.get("/is-admin", async (req, res) => {
|
||||||
return res.json({
|
return res.json({
|
||||||
isAdmin: true
|
isAdmin: true
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
admin.get("/users", async (req, res, next) => {
|
admin.get("/users", async (req, res, next) => {
|
||||||
try {
|
try {
|
||||||
const users = await User.findAll({
|
const users = await User.findAll({
|
||||||
attributes: {
|
attributes: {
|
||||||
exclude: ["password"],
|
exclude: ["password"],
|
||||||
include: ["id", "username", "createdAt", "updatedAt"]
|
include: ["id", "username", "createdAt", "updatedAt"]
|
||||||
},
|
},
|
||||||
include: [
|
include: [
|
||||||
{
|
{
|
||||||
model: Post,
|
model: Post,
|
||||||
as: "posts",
|
as: "posts",
|
||||||
attributes: ["id"]
|
attributes: ["id"]
|
||||||
}
|
}
|
||||||
],
|
]
|
||||||
})
|
})
|
||||||
res.json(users)
|
res.json(users)
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
next(e)
|
next(e)
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
admin.get("/posts", async (req, res, next) => {
|
admin.get("/posts", async (req, res, next) => {
|
||||||
try {
|
try {
|
||||||
const posts = await Post.findAll({
|
const posts = await Post.findAll({
|
||||||
attributes: {
|
attributes: {
|
||||||
exclude: ["content"],
|
exclude: ["content"],
|
||||||
include: ["id", "title", "visibility", "createdAt"]
|
include: ["id", "title", "visibility", "createdAt"]
|
||||||
},
|
},
|
||||||
include: [
|
include: [
|
||||||
{
|
{
|
||||||
model: File,
|
model: File,
|
||||||
as: "files",
|
as: "files",
|
||||||
attributes: ["id", "title", "createdAt", "html"]
|
attributes: ["id", "title", "createdAt", "html"]
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
model: User,
|
model: User,
|
||||||
as: "users",
|
as: "users",
|
||||||
attributes: ["id", "username"]
|
attributes: ["id", "username"]
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
})
|
})
|
||||||
res.json(posts)
|
res.json(posts)
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
next(e)
|
next(e)
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
admin.get("/post/:id", async (req, res, next) => {
|
admin.get("/post/:id", async (req, res, next) => {
|
||||||
try {
|
try {
|
||||||
const post = await Post.findByPk(req.params.id, {
|
const post = await Post.findByPk(req.params.id, {
|
||||||
attributes: {
|
attributes: {
|
||||||
exclude: ["content"],
|
exclude: ["content"],
|
||||||
include: ["id", "title", "visibility", "createdAt"]
|
include: ["id", "title", "visibility", "createdAt"]
|
||||||
},
|
},
|
||||||
include: [
|
include: [
|
||||||
{
|
{
|
||||||
model: File,
|
model: File,
|
||||||
as: "files",
|
as: "files",
|
||||||
attributes: ["id", "title", "sha", "createdAt", "updatedAt", "html"]
|
attributes: ["id", "title", "sha", "createdAt", "updatedAt", "html"]
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
model: User,
|
model: User,
|
||||||
as: "users",
|
as: "users",
|
||||||
attributes: ["id", "username"]
|
attributes: ["id", "username"]
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
})
|
})
|
||||||
if (!post) {
|
if (!post) {
|
||||||
return res.status(404).json({
|
return res.status(404).json({
|
||||||
message: "Post not found"
|
message: "Post not found"
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
res.json(post)
|
res.json(post)
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
next(e)
|
next(e)
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
admin.delete("/post/:id", async (req, res, next) => {
|
admin.delete("/post/:id", async (req, res, next) => {
|
||||||
try {
|
try {
|
||||||
const post = await Post.findByPk(req.params.id)
|
const post = await Post.findByPk(req.params.id)
|
||||||
if (!post) {
|
if (!post) {
|
||||||
return res.status(404).json({
|
return res.status(404).json({
|
||||||
message: "Post not found"
|
message: "Post not found"
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
if (post.files?.length)
|
if (post.files?.length)
|
||||||
await Promise.all(post.files.map((file) => file.destroy()))
|
await Promise.all(post.files.map((file) => file.destroy()))
|
||||||
await post.destroy({ force: true })
|
await post.destroy({ force: true })
|
||||||
res.json({
|
res.json({
|
||||||
message: "Post deleted"
|
message: "Post deleted"
|
||||||
})
|
})
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
next(e)
|
next(e)
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
|
|
|
@ -68,7 +68,10 @@ auth.post(
|
||||||
const user = {
|
const user = {
|
||||||
username: username as string,
|
username: username as string,
|
||||||
password: await hash(req.body.password, salt),
|
password: await hash(req.body.password, salt),
|
||||||
role: (!!process.env.MEMORY_DB && process.env.ENABLE_ADMIN && count === 0) ? "admin" : "user"
|
role:
|
||||||
|
!!process.env.MEMORY_DB && process.env.ENABLE_ADMIN && count === 0
|
||||||
|
? "admin"
|
||||||
|
: "user"
|
||||||
}
|
}
|
||||||
|
|
||||||
const created_user = await User.create(user)
|
const created_user = await User.create(user)
|
||||||
|
|
|
@ -80,7 +80,7 @@ posts.post(
|
||||||
.update(file.content)
|
.update(file.content)
|
||||||
.digest("hex")
|
.digest("hex")
|
||||||
.toString(),
|
.toString(),
|
||||||
html: html || '',
|
html: html || "",
|
||||||
userId: req.body.userId,
|
userId: req.body.userId,
|
||||||
postId: newPost.id
|
postId: newPost.id
|
||||||
})
|
})
|
||||||
|
@ -183,9 +183,7 @@ posts.get(
|
||||||
{ "$files.title$": { [Op.like]: `%${q}%` } },
|
{ "$files.title$": { [Op.like]: `%${q}%` } },
|
||||||
{ "$files.content$": { [Op.like]: `%${q}%` } }
|
{ "$files.content$": { [Op.like]: `%${q}%` } }
|
||||||
],
|
],
|
||||||
[Op.and]: [
|
[Op.and]: [{ "$users.id$": req.user?.id || "" }]
|
||||||
{ "$users.id$": req.user?.id || "" },
|
|
||||||
]
|
|
||||||
},
|
},
|
||||||
include: [
|
include: [
|
||||||
{
|
{
|
||||||
|
@ -195,7 +193,7 @@ posts.get(
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
model: User,
|
model: User,
|
||||||
as: "users",
|
as: "users"
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
attributes: ["id", "title", "visibility", "createdAt", "deletedAt"],
|
attributes: ["id", "title", "visibility", "createdAt", "deletedAt"],
|
||||||
|
@ -296,7 +294,6 @@ posts.delete("/:id", jwt, async (req: UserJwtRequest, res, next) => {
|
||||||
return res.status(404).json({ error: "Post not found" })
|
return res.status(404).json({ error: "Post not found" })
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
if (req.user?.id !== post.users![0].id) {
|
if (req.user?.id !== post.users![0].id) {
|
||||||
return res.status(403).json({ error: "Forbidden" })
|
return res.status(403).json({ error: "Forbidden" })
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,9 +2,9 @@ import { createServer } from "http"
|
||||||
import { app } from "./app"
|
import { app } from "./app"
|
||||||
import config from "./lib/config"
|
import config from "./lib/config"
|
||||||
import "./database"
|
import "./database"
|
||||||
; (async () => {
|
;(async () => {
|
||||||
// await sequelize.sync()
|
// await sequelize.sync()
|
||||||
createServer(app).listen(config.port, () =>
|
createServer(app).listen(config.port, () =>
|
||||||
console.info(`Server running on port ${config.port}`)
|
console.info(`Server running on port ${config.port}`)
|
||||||
)
|
)
|
||||||
})()
|
})()
|
||||||
|
|
Loading…
Reference in a new issue