additions
This commit is contained in:
parent
dbb03e6325
commit
4a1b8348b0
@ -1,5 +1,5 @@
|
|||||||
{
|
{
|
||||||
"name": "webface",
|
"name": "webface-server",
|
||||||
"version": "1.0.0",
|
"version": "1.0.0",
|
||||||
"description": "",
|
"description": "",
|
||||||
"main": "index.js",
|
"main": "index.js",
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
{
|
{
|
||||||
"name": "webface",
|
"name": "webface-server",
|
||||||
"plugins": [
|
"plugins": [
|
||||||
{
|
{
|
||||||
"name": "webface",
|
"name": "webface",
|
||||||
|
@ -45,13 +45,11 @@ class WebSocketServer extends EventEmitter {
|
|||||||
constructor(
|
constructor(
|
||||||
public port: number,
|
public port: number,
|
||||||
public host: string,
|
public host: string,
|
||||||
trustProxy = false,
|
private authorizedURL: string,
|
||||||
|
private trustProxy = false,
|
||||||
) {
|
) {
|
||||||
super();
|
super();
|
||||||
this.app.disable('x-powered-by');
|
this.setupApp();
|
||||||
if (trustProxy) {
|
|
||||||
this.app.set('trust proxy', 1);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public init(): void {
|
public init(): void {
|
||||||
@ -66,6 +64,21 @@ class WebSocketServer extends EventEmitter {
|
|||||||
this.wss.close();
|
this.wss.close();
|
||||||
this.server.close();
|
this.server.close();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private setupApp(): void {
|
||||||
|
this.app.disable('x-powered-by');
|
||||||
|
if (this.trustProxy) {
|
||||||
|
this.app.set('trust proxy', 1);
|
||||||
|
}
|
||||||
|
this.app.use(express.json() as RequestHandler);
|
||||||
|
this.app.use((req, res, next) => {
|
||||||
|
res.header('Access-Control-Allow-Origin', this.authorizedURL);
|
||||||
|
res.header('Access-Control-Allow-Methods', 'POST, GET, DELETE, OPTIONS');
|
||||||
|
res.header('Access-Control-Allow-Headers', 'Origin, X-Requested-With, Content-Type, Accept, Authorization');
|
||||||
|
res.header('Access-Control-Allow-Credentials', 'true');
|
||||||
|
next();
|
||||||
|
});
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
class WebfaceServer extends WebSocketServer {
|
class WebfaceServer extends WebSocketServer {
|
||||||
@ -74,13 +87,13 @@ class WebfaceServer extends WebSocketServer {
|
|||||||
private issuedTokens = new Map<string, string>();
|
private issuedTokens = new Map<string, string>();
|
||||||
|
|
||||||
constructor(
|
constructor(
|
||||||
public port: number,
|
port: number,
|
||||||
public host: string,
|
host: string,
|
||||||
public authorizedURL: string,
|
authorizedURL: string,
|
||||||
private users: RegisteredUser[],
|
|
||||||
trustProxy = false,
|
trustProxy = false,
|
||||||
|
private users: RegisteredUser[],
|
||||||
) {
|
) {
|
||||||
super(port, host, trustProxy);
|
super(port, host, authorizedURL, trustProxy);
|
||||||
this.initializeWebSocket();
|
this.initializeWebSocket();
|
||||||
this.initializeAPI();
|
this.initializeAPI();
|
||||||
}
|
}
|
||||||
@ -196,10 +209,11 @@ class WebfaceServer extends WebSocketServer {
|
|||||||
* @param ws WebSocket client
|
* @param ws WebSocket client
|
||||||
* @param username Client's username
|
* @param username Client's username
|
||||||
*/
|
*/
|
||||||
private sendStatus(ws: WebSocket, username: string): void {
|
private sendStatus(ws: WebSocket, username: string, state?: string): void {
|
||||||
ws.send(JSON.stringify({
|
ws.send(JSON.stringify({
|
||||||
status: this.controlPlugin ? 'OK' : 'MISSING_CONTROL',
|
status: this.controlPlugin ? 'OK' : 'MISSING_CONTROL',
|
||||||
commands: this.controlPlugin?.listControlCommands() || [],
|
commands: this.controlPlugin?.listControlCommands() || [],
|
||||||
|
state,
|
||||||
user: {
|
user: {
|
||||||
username,
|
username,
|
||||||
}
|
}
|
||||||
@ -230,7 +244,7 @@ class WebfaceServer extends WebSocketServer {
|
|||||||
status: 'ERROR',
|
status: 'ERROR',
|
||||||
message: 'Unknown or missing command',
|
message: 'Unknown or missing command',
|
||||||
command: '',
|
command: '',
|
||||||
state: jCmd.state,
|
state,
|
||||||
}));
|
}));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -241,7 +255,7 @@ class WebfaceServer extends WebSocketServer {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (command === 'help' || command === 'status') {
|
if (command === 'help' || command === 'status') {
|
||||||
this.sendStatus(ws, user);
|
this.sendStatus(ws, user, state);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -312,37 +326,10 @@ class WebfaceServer extends WebSocketServer {
|
|||||||
* Set up the HTTP API
|
* Set up the HTTP API
|
||||||
*/
|
*/
|
||||||
private initializeAPI(): void {
|
private initializeAPI(): void {
|
||||||
this.app.use(express.json() as RequestHandler);
|
|
||||||
this.app.use((req, res, next) => {
|
|
||||||
res.header('Access-Control-Allow-Origin', this.authorizedURL);
|
|
||||||
res.header('Access-Control-Allow-Methods', 'POST, GET, DELETE, OPTIONS');
|
|
||||||
res.header('Access-Control-Allow-Headers', 'Origin, X-Requested-With, Content-Type, Accept, Authorization');
|
|
||||||
res.header('Access-Control-Allow-Credentials', 'true');
|
|
||||||
next();
|
|
||||||
});
|
|
||||||
|
|
||||||
const router = express.Router();
|
const router = express.Router();
|
||||||
const authMiddleware = this.tokenOwnerMiddleware();
|
const authMiddleware = this.tokenOwnerMiddleware();
|
||||||
|
|
||||||
router.get('/', (req, res) => {
|
router.get('/', (req, res) => res.json({ status: 'OK'}));
|
||||||
res.json({
|
|
||||||
status: 'OK',
|
|
||||||
uptime: process.uptime(),
|
|
||||||
connections: this.connections.size,
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
router.get('/squeebot', authMiddleware, (req, res) => {
|
|
||||||
res.json({
|
|
||||||
status: this.controlPlugin ? 'OK' : 'MISSING_CONTROL',
|
|
||||||
uptime: process.uptime(),
|
|
||||||
connections: this.connections.size,
|
|
||||||
user: {
|
|
||||||
username: res.locals.user,
|
|
||||||
},
|
|
||||||
commands: this.controlPlugin?.listControlCommands() || [],
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
router.post('/authorize', (req, res) => {
|
router.post('/authorize', (req, res) => {
|
||||||
const { body: { username, password } } = req;
|
const { body: { username, password } } = req;
|
||||||
@ -372,8 +359,39 @@ class WebfaceServer extends WebSocketServer {
|
|||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
router.post('/introspect', authMiddleware, (req, res) => {
|
router.get('/squeebot', authMiddleware, (req, res) => {
|
||||||
res.json({ status: 'OK', message: 'Token valid', user: { username: res.locals.user } });
|
res.json({
|
||||||
|
status: this.controlPlugin ? 'OK' : 'MISSING_CONTROL',
|
||||||
|
uptime: process.uptime(),
|
||||||
|
connections: this.connections.size,
|
||||||
|
user: {
|
||||||
|
username: res.locals.user,
|
||||||
|
},
|
||||||
|
commands: this.controlPlugin?.listControlCommands() || [],
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
router.post('/verify', authMiddleware,
|
||||||
|
(req, res) => res.json({
|
||||||
|
status: 'OK',
|
||||||
|
message: 'Token valid',
|
||||||
|
user: {
|
||||||
|
username: res.locals.user
|
||||||
|
}
|
||||||
|
}));
|
||||||
|
|
||||||
|
router.post('/password', authMiddleware, (req, res) => {
|
||||||
|
const { password } = req.body;
|
||||||
|
if (!password || password.length < 8) {
|
||||||
|
return res.status(400).json({
|
||||||
|
error: 'invalid_password',
|
||||||
|
error_message: 'Password must be at least 8 characters long.',
|
||||||
|
});
|
||||||
|
}
|
||||||
|
this.emit('chpwd', { password, user: res.locals.user });
|
||||||
|
res.json({
|
||||||
|
status: 'OK'
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
router.delete('/token', authMiddleware, (req, res) => {
|
router.delete('/token', authMiddleware, (req, res) => {
|
||||||
@ -521,10 +539,23 @@ class WebfacePlugin extends Plugin {
|
|||||||
this.config.get('port') as number,
|
this.config.get('port') as number,
|
||||||
this.config.get('host'),
|
this.config.get('host'),
|
||||||
this.config.get('trustedRemote', '*') as string,
|
this.config.get('trustedRemote', '*') as string,
|
||||||
users,
|
|
||||||
this.config.get('trustProxy', false),
|
this.config.get('trustProxy', false),
|
||||||
|
users,
|
||||||
);
|
);
|
||||||
|
|
||||||
|
this.srv.on('chpwd', ({ user, password }) => {
|
||||||
|
const currentUsers = this.config.get('users');
|
||||||
|
const currentUser = currentUsers.find(({ username }: RegisteredUser) => username === user);
|
||||||
|
if (currentUsers) {
|
||||||
|
bcrypt.hash(password, 10).then((hashed) => {
|
||||||
|
currentUser.password = hashed;
|
||||||
|
logger.warn('[webface] User %s password changed.', user);
|
||||||
|
this.config.set('users', currentUsers);
|
||||||
|
this.config.save().catch((e) => logger.error('[webface] Failed to save users:', e.message));
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
this.srv.init();
|
this.srv.init();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user