feat(preferences): added support for server-based preferences, rather than client-based

re #4
This commit is contained in:
Will Moss
2024-07-16 15:51:43 +07:00
parent 57febeb147
commit b4c6aade5e
5 changed files with 58 additions and 3 deletions

View File

@@ -67,6 +67,13 @@
});
};
/**
* Determine whether a key-value association exists in the localStorage
* @param {string} key
* @returns {boolean}
*/
const lsExists = (key) => (localStorage.getItem(key) === null ? false : true);
/**
* Retrieve a value from localStorage, with support for booleans and default value
* @param {string} key
@@ -84,7 +91,7 @@
/**
* Determine the general type of a variable
* @param {*} v
* @returns {'string'|'numeric'|'date'}
* @returns {'string'|'numeric'}
*/
const getGeneralType = (v) => {
if (typeof v !== 'string') v = v.toString();
@@ -4285,6 +4292,32 @@
break;
case 'auth':
// Load server-sent preferences if any
if ('Preferences' in notification.Content) {
for (const entry of Object.entries(
notification.Content.Preferences
)) {
// Camelize the the original key
const newKey = entry[0]
.replace('CLIENT_PREFERENCE_', '')
.toLowerCase()
.replace(/[^a-zA-Z0-9]+(.)/g, (m, chr) => chr.toUpperCase());
// Turn the stringified value into a typed variable
let newValue = null;
if (['true', '1', 'on'].includes(entry[1].toLowerCase()))
newValue = true;
else if (['false', '0', 'off'].includes(entry[1].toLowerCase()))
newValue = false;
else newValue = entry[1];
// Update the current preferences if unset
if (!lsExists(newKey))
if (newKey !== 'theme') state.settings[newKey] = newValue;
else state.appearance.currentTheme = newValue;
}
}
if ('Authentication' in notification.Content) {
state.message.category = 'authentication';
state.message.type = notification.Type;

View File

@@ -23,6 +23,7 @@ func (Authentication) RunCommand(server *Server, session _session.GenericSession
"Authentication": ui.JSON{
"Message": "Your are now authenticated",
},
"Preferences": server.GetPreferences(),
},
}))
break
@@ -82,6 +83,7 @@ func (Authentication) RunCommand(server *Server, session _session.GenericSession
"Authentication": ui.JSON{
"Message": "Your are now authenticated",
},
"Preferences": server.GetPreferences(),
},
}),
)

View File

@@ -114,7 +114,11 @@ func (server *Server) runCommand(session _session.GenericSession, command ui.Com
server.SendNotification(
session,
ui.NotificationInit(ui.NotificationParams{
Content: ui.JSON{"Tabs": tabs, "Agents": agents, "Hosts": hosts},
Content: ui.JSON{
"Tabs": tabs,
"Agents": agents,
"Hosts": hosts,
},
}))
} else if command.Action == "enumerate" {
// `enumerate` is used only in the context of the `Jump` command
@@ -325,6 +329,7 @@ func (server *Server) Handle(session _session.GenericSession, message ...[]byte)
"Spontaneous": true,
"Message": "Your are now authenticated",
},
"Preferences": server.GetPreferences(),
},
}))
}
@@ -456,3 +461,14 @@ func (s *Server) SetHost(name string) {
s.Docker = _client.NewClientWithOpts(client.WithHost(correspondingHost[1]))
s.CurrentHostName = name
}
func (s *Server) GetPreferences() ui.Preferences {
var preferences = make(ui.Preferences, 0)
for k, v := range _os.GetFullEnv() {
if strings.HasPrefix(k, "CLIENT_PREFERENCE_") {
preferences[k] = v
}
}
return preferences
}

View File

@@ -0,0 +1,4 @@
package ui
// Represent a JS preference in the web browser
type Preferences map[string]string

View File

@@ -1,5 +1,5 @@
package ui
// Represent
// Represent a row in the web browser
type Row map[string]interface{}
type Rows []Row