Implement user/password configured auth

This commit is contained in:
Daniel McKnight 2024-10-04 08:21:38 -07:00
parent 0e7350086d
commit 133aa45ef8
2 changed files with 82 additions and 34 deletions

103
applet.js
View file

@ -6,6 +6,7 @@ const Mainloop = imports.mainloop;
const Soup = imports.gi.Soup; const Soup = imports.gi.Soup;
const St = imports.gi.St; const St = imports.gi.St;
const Settings = imports.ui.settings; const Settings = imports.ui.settings;
const Json = imports.gi.Json;
function MyApplet(metadata, orientation, panel_height, instance_id) { function MyApplet(metadata, orientation, panel_height, instance_id) {
this._init(metadata, orientation, panel_height, instance_id); this._init(metadata, orientation, panel_height, instance_id);
@ -30,8 +31,16 @@ MyApplet.prototype = {
this.settings.bindProperty( this.settings.bindProperty(
Settings.BindingDirection.IN, Settings.BindingDirection.IN,
"token", "username",
"token", "username",
this.onSettingsChanged,
null
);
this.settings.bindProperty(
Settings.BindingDirection.IN,
"password",
"password",
this.onSettingsChanged, this.onSettingsChanged,
null null
); );
@ -46,20 +55,10 @@ MyApplet.prototype = {
this._player = null; this._player = null;
this._audioBuffer = new Uint8Array(0); this._audioBuffer = new Uint8Array(0);
this._playbackBuffer = []; this._playbackBuffer = [];
this._accessToken = null;
global.log("[Voice Assistant] Applet initialized"); global.log("[Voice Assistant] Applet initialized");
this._initSockets(); this._authenticate();
},
onSettingsChanged: function() {
global.log("[Voice Assistant] Settings changed, reinitializing sockets");
if (this._streamSocket) {
this._streamSocket.close(Soup.WebsocketCloseCode.NORMAL, null);
}
if (this._nodeSocket) {
this._nodeSocket.close(Soup.WebsocketCloseCode.NORMAL, null);
}
this._initSockets();
}, },
_setCustomIcon: function(iconPath) { _setCustomIcon: function(iconPath) {
@ -75,12 +74,56 @@ MyApplet.prototype = {
} }
}, },
onSettingsChanged: function() {
global.log("[Voice Assistant] Settings changed, re-authenticating");
this._closeExistingSockets();
this._authenticate();
},
_authenticate: function() {
let session = new Soup.Session();
let message = Soup.Message.new(
'POST',
`https://${this.baseUrl}/auth/login`
);
let body = JSON.stringify({
username: this.username,
password: this.password
});
let bytes = GLib.Bytes.new(body);
message.set_request_body_from_bytes('application/json', bytes);
session.send_and_read_async(message, GLib.PRIORITY_DEFAULT, null, (session, result) => {
try {
let bytes = session.send_and_read_finish(result);
if (message.get_status() === 200) {
let data = JSON.parse(new TextDecoder().decode(bytes.get_data()));
this._accessToken = data.access_token;
global.log("[Voice Assistant] Authentication successful");
this._initSockets();
} else {
global.logError("[Voice Assistant] Authentication failed: " + message.get_status());
}
} catch (e) {
global.logError("[Voice Assistant] Error during authentication: " + e.message);
}
});
},
_initSockets: function() { _initSockets: function() {
if (!this._accessToken) {
global.logError("[Voice Assistant] No access token available. Cannot initialize sockets.");
return;
}
global.log("[Voice Assistant] Initializing WebSockets"); global.log("[Voice Assistant] Initializing WebSockets");
let maxPayloadSize = 10 * 1024 * 1024; // 10 MB in bytes let maxPayloadSize = 10 * 1024 * 1024; // 10 MB in bytes
const STREAM_SOCKET_URL = `wss://${this.baseUrl}/node/v1/stream?token=${this.token}`; const STREAM_SOCKET_URL = `wss://${this.baseUrl}/node/v1/stream?token=${this._accessToken}`;
const NODE_SOCKET_URL = `wss://${this.baseUrl}/node/v1?token=${this.token}`; const NODE_SOCKET_URL = `wss://${this.baseUrl}/node/v1?token=${this._accessToken}`;
// Initialize Node WebSocket // Initialize Node WebSocket
try { try {
@ -128,14 +171,21 @@ MyApplet.prototype = {
} }
}, },
_closeExistingSockets: function() {
if (this._streamSocket) {
this._streamSocket.close(Soup.WebsocketCloseCode.NORMAL, null);
this._streamSocket = null;
}
if (this._nodeSocket) {
this._nodeSocket.close(Soup.WebsocketCloseCode.NORMAL, null);
this._nodeSocket = null;
}
},
_onSocketError: function(socket, error) { _onSocketError: function(socket, error) {
global.logError("[Voice Assistant] WebSocket error: " + error.message); global.logError("[Voice Assistant] WebSocket error: " + error.message);
try { this._closeExistingSockets();
this._streamSocket.close(); this._authenticate();
this._nodeSocket.close();
} finally {
this._initSockets();
}
}, },
_onNodeMessage: function(connection, type, message) { _onNodeMessage: function(connection, type, message) {
@ -317,14 +367,7 @@ MyApplet.prototype = {
on_applet_removed_from_panel: function() { on_applet_removed_from_panel: function() {
global.log("[Voice Assistant] Applet removed from panel"); global.log("[Voice Assistant] Applet removed from panel");
this._stopRecording(); this._stopRecording();
if (this._streamSocket) { this._closeExistingSockets();
this._streamSocket.close(Soup.WebsocketCloseCode.NORMAL, null);
global.log("[Voice Assistant] Record WebSocket closed");
}
if (this._nodeSocket) {
this._nodeSocket.close(Soup.WebsocketCloseCode.NORMAL, null);
global.log("[Voice Assistant] Node WebSocket closed");
}
if (this._player) { if (this._player) {
this._player.force_exit(); this._player.force_exit();
global.log("[Voice Assistant] Audio player terminated"); global.log("[Voice Assistant] Audio player terminated");

View file

@ -2,11 +2,16 @@
"baseUrl": { "baseUrl": {
"type": "entry", "type": "entry",
"default": "hana.neonaialpha.com", "default": "hana.neonaialpha.com",
"description": "Base URL for HANA Websocket" "description": "Base URL for the Voice Assistant service"
}, },
"token": { "username": {
"type": "entry", "type": "entry",
"default": "", "default": "neon",
"description": "Valid token for authentication" "description": "Username for authentication"
},
"password": {
"type": "entry",
"default": "neon",
"description": "Password for authentication"
} }
} }