Merge pull request #56 from ragestudio/linebridge-update

Linebridge update
This commit is contained in:
srgooglo 2022-05-06 19:01:21 +02:00 committed by GitHub
commit b7837284a9
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
19 changed files with 79 additions and 71 deletions

View File

@ -43,7 +43,7 @@
"js-cookie": "3.0.1", "js-cookie": "3.0.1",
"jwt-decode": "3.1.2", "jwt-decode": "3.1.2",
"less": "4.1.2", "less": "4.1.2",
"linebridge": "0.10.13", "linebridge": "0.11.13",
"moment": "2.29.1", "moment": "2.29.1",
"mpegts.js": "^1.6.10", "mpegts.js": "^1.6.10",
"nprogress": "^0.2.0", "nprogress": "^0.2.0",

View File

@ -14,8 +14,8 @@ const steps = [
content: (props) => { content: (props) => {
return <div className="workorder_creator steps step content"> return <div className="workorder_creator steps step content">
<antd.Input <antd.Input
autocorrect="off" autoCorrect="off"
autocapitalize="none" autoCapitalize="none"
onPressEnter={props.onPressEnter} onPressEnter={props.onPressEnter}
placeholder="@newuser" placeholder="@newuser"
onChange={(e) => { onChange={(e) => {
@ -34,8 +34,8 @@ const steps = [
content: (props) => { content: (props) => {
return <div className="workorder_creator steps step content"> return <div className="workorder_creator steps step content">
<antd.Input.Password <antd.Input.Password
autocorrect="off" autoCorrect="off"
autocapitalize="none" autoCapitalize="none"
onPressEnter={props.onPressEnter} onPressEnter={props.onPressEnter}
placeholder="Password" placeholder="Password"
onChange={(e) => { onChange={(e) => {

View File

@ -63,11 +63,13 @@ export default class ApiExtension extends Extension {
} }
const handleResponse = async (data) => { const handleResponse = async (data) => {
// handle token regeneration
if (data.headers?.regenerated_token) { if (data.headers?.regenerated_token) {
Session.token = data.headers.regenerated_token Session.token = data.headers.regenerated_token
console.debug("[REGENERATION] New token generated") console.debug("[REGENERATION] New token generated")
} }
// handle 401 responses
if (data instanceof Error) { if (data instanceof Error) {
if (data.response.status === 401) { if (data.response.status === 401) {
window.app.eventBus.emit("invalid_session") window.app.eventBus.emit("invalid_session")

View File

@ -7,6 +7,7 @@ export default class ShortcutsExtension extends Extension {
this.shortcuts = {} this.shortcuts = {}
document.addEventListener("keydown", (event) => { document.addEventListener("keydown", (event) => {
// FIXME: event.key sometimes is not defined
const key = event.key.toLowerCase() const key = event.key.toLowerCase()
const shortcut = this.shortcuts[key] const shortcut = this.shortcuts[key]

View File

@ -44,8 +44,8 @@ export default class Session {
//* BASIC HANDLERS //* BASIC HANDLERS
login = (payload, callback) => { login = (payload, callback) => {
const body = { const body = {
username: window.btoa(payload.username), username: payload.username, //window.btoa(payload.username),
password: window.btoa(payload.password), password: payload.password, //window.btoa(payload.password),
} }
return this.generateNewToken(body, (err, res) => { return this.generateNewToken(body, (err, res) => {

View File

@ -15,8 +15,8 @@ const formInstance = [
icon: "User", icon: "User",
placeholder: "Username", placeholder: "Username",
props: { props: {
autocorrect: "off", autoCorrect: "off",
autocapitalize: "none", autoCapitalize: "none",
className: "login-form-username", className: "login-form-username",
}, },
}, },

View File

@ -8,14 +8,13 @@
"license": "MIT", "license": "MIT",
"dependencies": { "dependencies": {
"@corenode/utils": "0.28.26", "@corenode/utils": "0.28.26",
"@nanoexpress/middleware-file-upload": "^1.0.6",
"axios": "0.25.0", "axios": "0.25.0",
"bcrypt": "5.0.1", "bcrypt": "5.0.1",
"connect-mongo": "4.6.0", "connect-mongo": "4.6.0",
"corenode": "0.28.26", "corenode": "0.28.26",
"dicebar_lib": "1.0.1", "dicebar_lib": "1.0.1",
"jsonwebtoken": "8.5.1", "jsonwebtoken": "8.5.1",
"linebridge": "0.10.13", "linebridge": "0.11.13",
"moment": "2.29.1", "moment": "2.29.1",
"mongoose": "6.1.9", "mongoose": "6.1.9",
"nanoid": "3.2.0", "nanoid": "3.2.0",

View File

@ -1,6 +1,6 @@
import { ComplexController } from "linebridge/dist/classes" import { Controller } from "linebridge/dist/server"
export default class ConfigController extends ComplexController { export default class ConfigController extends Controller {
static refName = "ConfigController" static refName = "ConfigController"
static useMiddlewares = ["withAuthentication", "onlyAdmin"] static useMiddlewares = ["withAuthentication", "onlyAdmin"]

View File

@ -1,4 +1,4 @@
import { ComplexController } from "linebridge/dist/classes" import { Controller } from "linebridge/dist/server"
import path from "path" import path from "path"
import fs from "fs" import fs from "fs"
import stream from "stream" import stream from "stream"
@ -7,28 +7,32 @@ function resolveToUrl(filepath) {
return `${global.globalPublicURI}/uploads/${filepath}` return `${global.globalPublicURI}/uploads/${filepath}`
} }
export default class FilesController extends ComplexController { export default class FilesController extends Controller {
static refName = "FilesController" static disabled = true
get = { get = {
"/uploads/:id": (req, res) => { "/uploads/:id": {
const filePath = path.join(global.uploadPath, req.params?.id) enabled: false,
fn: (req, res) => {
const filePath = path.join(global.uploadPath, req.params?.id)
const readStream = fs.createReadStream(filePath) const readStream = fs.createReadStream(filePath)
const passTrough = new stream.PassThrough() const passTrough = new stream.PassThrough()
stream.pipeline(readStream, passTrough, (err) => { stream.pipeline(readStream, passTrough, (err) => {
if (err) { if (err) {
return res.status(400) return res.status(400)
} }
}) })
return passTrough.pipe(res) return passTrough.pipe(res)
},
} }
} }
post = { post = {
"/upload": { "/upload": {
enabled: false,
middlewares: ["withAuthentication", "fileUpload"], middlewares: ["withAuthentication", "fileUpload"],
fn: async (req, res) => { fn: async (req, res) => {
const urls = [] const urls = []

View File

@ -1,8 +1,8 @@
import { ComplexController } from "linebridge/dist/classes" import { Controller } from "linebridge/dist/server"
import { Schematized } from "../../lib" import { Schematized } from "../../lib"
import { Post, User } from "../../models" import { Post, User } from "../../models"
export default class PostsController extends ComplexController { export default class PostsController extends Controller {
static refName = "PostsController" static refName = "PostsController"
static useMiddlewares = ["withAuthentication"] static useMiddlewares = ["withAuthentication"]

View File

@ -1,6 +1,6 @@
import { ComplexController } from "linebridge/dist/classes" import { Controller } from "linebridge/dist/server"
export default class PublicController extends ComplexController { export default class PublicController extends Controller {
static refName = "PublicController" static refName = "PublicController"
post = { post = {

View File

@ -1,8 +1,8 @@
import { ComplexController } from "linebridge/dist/classes" import { Controller } from "linebridge/dist/server"
import { Role, User } from "../../models" import { Role, User } from "../../models"
import { Schematized } from "../../lib" import { Schematized } from "../../lib"
export default class RolesController extends ComplexController { export default class RolesController extends Controller {
static refName = "RolesController" static refName = "RolesController"
static useMiddlewares = ["roles"] static useMiddlewares = ["roles"]
@ -61,11 +61,11 @@ export default class RolesController extends ComplexController {
}, async (req, res) => { }, async (req, res) => {
// check if issuer user is admin // check if issuer user is admin
if (!req.isAdmin()) { if (!req.isAdmin()) {
return res.status(403).send("You do not have administrator permission") return res.status(403).json("You do not have administrator permission")
} }
if (!Array.isArray(req.selection.update)) { if (!Array.isArray(req.selection.update)) {
return res.status(400).send("Invalid update request") return res.status(400).json("Invalid update request")
} }
req.selection.update.forEach(async (update) => { req.selection.update.forEach(async (update) => {
@ -82,7 +82,7 @@ export default class RolesController extends ComplexController {
} }
}) })
return res.send("done") return res.json("done")
}), }),
}, },
} }

View File

@ -1,8 +1,8 @@
import { ComplexController } from "linebridge/dist/classes" import { Controller } from "linebridge/dist/server"
import { Session } from "../../models" import { Session } from "../../models"
import jwt from "jsonwebtoken" import jwt from "jsonwebtoken"
export default class SessionController extends ComplexController { export default class SessionController extends Controller {
static refName = "SessionController" static refName = "SessionController"
get = { get = {
@ -75,18 +75,18 @@ export default class SessionController extends ComplexController {
const { token, user_id } = req.body const { token, user_id } = req.body
if (typeof user_id === "undefined") { if (typeof user_id === "undefined") {
return res.status(400).send("No user_id provided") return res.status(400).json("No user_id provided")
} }
if (typeof token === "undefined") { if (typeof token === "undefined") {
return res.status(400).send("No token provided") return res.status(400).json("No token provided")
} }
const session = await Session.findOneAndDelete({ user_id, token }) const session = await Session.findOneAndDelete({ user_id, token })
if (session) { if (session) {
return res.send("done") return res.json("done")
} }
return res.status(404).send("not found") return res.status(404).json("not found")
}, },
}, },
"/sessions": { "/sessions": {
@ -95,15 +95,15 @@ export default class SessionController extends ComplexController {
const { user_id } = req.body const { user_id } = req.body
if (typeof user_id === "undefined") { if (typeof user_id === "undefined") {
return res.status(400).send("No user_id provided") return res.status(400).json("No user_id provided")
} }
const allSessions = await Session.deleteMany({ user_id }) const allSessions = await Session.deleteMany({ user_id })
if (allSessions) { if (allSessions) {
return res.send("done") return res.json("done")
} }
return res.status(404).send("not found") return res.status(404).json("not found")
} }
}, },
} }

View File

@ -1,6 +1,5 @@
import { ComplexController } from "linebridge/dist/classes" import { Controller } from "linebridge/dist/server"
import passport from "passport" import passport from "passport"
import { User, UserFollow } from "../../models" import { User, UserFollow } from "../../models"
import { Token, Schematized, createUser } from "../../lib" import { Token, Schematized, createUser } from "../../lib"
import SessionController from "../SessionController" import SessionController from "../SessionController"
@ -13,7 +12,7 @@ const AllowedPublicUpdateFields = [
"description", "description",
] ]
export default class UserController extends ComplexController { export default class UserController extends Controller {
static refName = "UserController" static refName = "UserController"
methods = { methods = {
@ -390,7 +389,7 @@ export default class UserController extends ComplexController {
}) })
}) })
.catch((err) => { .catch((err) => {
return res.send(500).json({ return res.json(500).json({
error: err.message error: err.message
}) })
}) })
@ -420,7 +419,7 @@ export default class UserController extends ComplexController {
}) })
}) })
.catch((err) => { .catch((err) => {
return res.send(500).json({ return res.json(500).json({
error: err.message error: err.message
}) })
}) })

View File

@ -1,3 +1,13 @@
// patches
const { Buffer } = require("buffer")
global.b64Decode = (data) => {
return Buffer.from(data, "base64").toString("utf-8")
}
global.b64Encode = (data) => {
return Buffer.from(data, "utf-8").toString("base64")
}
Array.prototype.updateFromObjectKeys = function (obj) { Array.prototype.updateFromObjectKeys = function (obj) {
this.forEach((value, index) => { this.forEach((value, index) => {
if (obj[value] !== undefined) { if (obj[value] !== undefined) {
@ -9,21 +19,13 @@ Array.prototype.updateFromObjectKeys = function (obj) {
} }
import path from "path" import path from "path"
import LinebridgeServer from "linebridge/dist/server" import { Server as LinebridgeServer } from "linebridge/dist/server"
import bcrypt from "bcrypt" import bcrypt from "bcrypt"
import mongoose from "mongoose" import mongoose from "mongoose"
import passport from "passport" import passport from "passport"
import { User, Session, Config } from "./models" import { User, Session, Config } from "./models"
import jwt from "jsonwebtoken" import jwt from "jsonwebtoken"
const { Buffer } = require("buffer")
const b64Decode = global.b64Decode = (data) => {
return Buffer.from(data, "base64").toString("utf-8")
}
const b64Encode = global.b64Encode = (data) => {
return Buffer.from(data, "utf-8").toString("base64")
}
const ExtractJwt = require("passport-jwt").ExtractJwt const ExtractJwt = require("passport-jwt").ExtractJwt
const LocalStrategy = require("passport-local").Strategy const LocalStrategy = require("passport-local").Strategy
@ -188,11 +190,11 @@ class Server {
passwordField: "password", passwordField: "password",
session: false session: false
}, (username, password, done) => { }, (username, password, done) => {
User.findOne({ username: b64Decode(username) }).select("+password") User.findOne({ username }).select("+password")
.then((data) => { .then((data) => {
if (data === null) { if (data === null) {
return done(null, false, this.options.jwtStrategy) return done(null, false, this.options.jwtStrategy)
} else if (!bcrypt.compareSync(b64Decode(password), data.password)) { } else if (!bcrypt.compareSync(password, data.password)) {
return done(null, false, this.options.jwtStrategy) return done(null, false, this.options.jwtStrategy)
} }

View File

@ -1,11 +1,12 @@
export default (schema = {}, fn) => { export default (schema = {}, fn) => {
return async (req, res, next) => { return async (req, res, next) => {
if (typeof req.body === "undefined") { // not necessary since linebridge lib will do this for you
req.body = {} // if (typeof req.body === "undefined") {
} // req.body = {}
if (typeof req.query === "undefined") { // }
req.query = {} // if (typeof req.query === "undefined") {
} // req.query = {}
// }
if (schema.required) { if (schema.required) {
if (Array.isArray(schema.required)) { if (Array.isArray(schema.required)) {

View File

@ -1,4 +1,4 @@
const fileUpload = require("@nanoexpress/middleware-file-upload/cjs")() // const fileUpload = require("@nanoexpress/middleware-file-upload/cjs")()
export { default as withAuthentication } from "./withAuthentication" export { default as withAuthentication } from "./withAuthentication"
export { default as errorHandler } from "./errorHandler" export { default as errorHandler } from "./errorHandler"
@ -7,4 +7,4 @@ export { default as roles } from "./roles"
export { default as onlyAdmin } from "./onlyAdmin" export { default as onlyAdmin } from "./onlyAdmin"
export { default as permissions } from "./permissions" export { default as permissions } from "./permissions"
export { fileUpload as fileUpload } // export { fileUpload as fileUpload }

View File

@ -1,6 +1,6 @@
export default (req, res, next) => { export default (req, res, next) => {
if (!req.user.roles.includes("admin")) { if (!req.user.roles.includes("admin")) {
return res.status(403).send({ error: "To make this request it is necessary to have administrator permissions" }) return res.status(403).json({ error: "To make this request it is necessary to have administrator permissions" })
} }
next() next()

View File

@ -4,7 +4,7 @@ import jwt from "jsonwebtoken"
export default (req, res, next) => { export default (req, res, next) => {
function reject(description) { function reject(description) {
return res.status(401).send({ error: `${description ?? "Invalid session"}` }) return res.status(401).json({ error: `${description ?? "Invalid session"}` })
} }
const authHeader = req.headers?.authorization?.split(" ") const authHeader = req.headers?.authorization?.split(" ")
@ -34,7 +34,7 @@ export default (req, res, next) => {
const userData = await User.findOne({ _id: currentSession.user_id }).select("+refreshToken") const userData = await User.findOne({ _id: currentSession.user_id }).select("+refreshToken")
if (!userData) { if (!userData) {
return res.status(404).send({ error: "No user data found" }) return res.status(404).json({ error: "No user data found" })
} }
if (err) { if (err) {