Implement user/password configured auth
This commit is contained in:
parent
0e7350086d
commit
133aa45ef8
2 changed files with 82 additions and 34 deletions
103
applet.js
103
applet.js
|
@ -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");
|
||||||
|
|
|
@ -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"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue