additions
This commit is contained in:
parent
dbb03e6325
commit
4a1b8348b0
@ -1,5 +1,5 @@
|
||||
{
|
||||
"name": "webface",
|
||||
"name": "webface-server",
|
||||
"version": "1.0.0",
|
||||
"description": "",
|
||||
"main": "index.js",
|
||||
|
@ -1,5 +1,5 @@
|
||||
{
|
||||
"name": "webface",
|
||||
"name": "webface-server",
|
||||
"plugins": [
|
||||
{
|
||||
"name": "webface",
|
||||
|
@ -45,13 +45,11 @@ class WebSocketServer extends EventEmitter {
|
||||
constructor(
|
||||
public port: number,
|
||||
public host: string,
|
||||
trustProxy = false,
|
||||
private authorizedURL: string,
|
||||
private trustProxy = false,
|
||||
) {
|
||||
super();
|
||||
this.app.disable('x-powered-by');
|
||||
if (trustProxy) {
|
||||
this.app.set('trust proxy', 1);
|
||||
}
|
||||
this.setupApp();
|
||||
}
|
||||
|
||||
public init(): void {
|
||||
@ -66,6 +64,21 @@ class WebSocketServer extends EventEmitter {
|
||||
this.wss.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 {
|
||||
@ -74,13 +87,13 @@ class WebfaceServer extends WebSocketServer {
|
||||
private issuedTokens = new Map<string, string>();
|
||||
|
||||
constructor(
|
||||
public port: number,
|
||||
public host: string,
|
||||
public authorizedURL: string,
|
||||
private users: RegisteredUser[],
|
||||
port: number,
|
||||
host: string,
|
||||
authorizedURL: string,
|
||||
trustProxy = false,
|
||||
private users: RegisteredUser[],
|
||||
) {
|
||||
super(port, host, trustProxy);
|
||||
super(port, host, authorizedURL, trustProxy);
|
||||
this.initializeWebSocket();
|
||||
this.initializeAPI();
|
||||
}
|
||||
@ -196,10 +209,11 @@ class WebfaceServer extends WebSocketServer {
|
||||
* @param ws WebSocket client
|
||||
* @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({
|
||||
status: this.controlPlugin ? 'OK' : 'MISSING_CONTROL',
|
||||
commands: this.controlPlugin?.listControlCommands() || [],
|
||||
state,
|
||||
user: {
|
||||
username,
|
||||
}
|
||||
@ -230,7 +244,7 @@ class WebfaceServer extends WebSocketServer {
|
||||
status: 'ERROR',
|
||||
message: 'Unknown or missing command',
|
||||
command: '',
|
||||
state: jCmd.state,
|
||||
state,
|
||||
}));
|
||||
return;
|
||||
}
|
||||
@ -241,7 +255,7 @@ class WebfaceServer extends WebSocketServer {
|
||||
}
|
||||
|
||||
if (command === 'help' || command === 'status') {
|
||||
this.sendStatus(ws, user);
|
||||
this.sendStatus(ws, user, state);
|
||||
return;
|
||||
}
|
||||
|
||||
@ -312,37 +326,10 @@ class WebfaceServer extends WebSocketServer {
|
||||
* Set up the HTTP API
|
||||
*/
|
||||
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 authMiddleware = this.tokenOwnerMiddleware();
|
||||
|
||||
router.get('/', (req, res) => {
|
||||
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.get('/', (req, res) => res.json({ status: 'OK'}));
|
||||
|
||||
router.post('/authorize', (req, res) => {
|
||||
const { body: { username, password } } = req;
|
||||
@ -372,8 +359,39 @@ class WebfaceServer extends WebSocketServer {
|
||||
});
|
||||
});
|
||||
|
||||
router.post('/introspect', authMiddleware, (req, res) => {
|
||||
res.json({ status: 'OK', message: 'Token valid', user: { username: res.locals.user } });
|
||||
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('/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) => {
|
||||
@ -521,10 +539,23 @@ class WebfacePlugin extends Plugin {
|
||||
this.config.get('port') as number,
|
||||
this.config.get('host'),
|
||||
this.config.get('trustedRemote', '*') as string,
|
||||
users,
|
||||
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();
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user