Hide some ENV values.

This commit is contained in:
Abdulmhsen B. A. A
2024-05-03 20:18:18 +03:00
parent 85fcc593cd
commit f587b68972
4 changed files with 83 additions and 6 deletions

View File

@@ -46,6 +46,11 @@ hr {
white-space: nowrap;
}
.is-masked {
color: transparent !important;
text-shadow: 0 0 8px rgba(0, 0, 0, 0.5);
}
@media (prefers-color-scheme: dark) {
* {
unicode-bidi: plaintext;
@@ -94,6 +99,10 @@ hr {
text-overflow: ellipsis;
white-space: nowrap;
}
.is-masked {
text-shadow: 0 0 8px rgba(255, 255, 255, 0.5);
}
}
.is-borderless {

View File

@@ -1,7 +1,7 @@
<template>
<div class="columns is-multiline">
<div class="column is-12 is-clearfix">
<span class="title is-4">Environment Variables</span>
<span id="env_page_title" class="title is-4">Environment Variables</span>
<div class="is-pulled-right">
<div class="field is-grouped">
@@ -29,7 +29,7 @@
</div>
<div class="column is-12" v-if="toggleForm">
<form @submit.prevent="addVariable">
<form id="env_add_form" @submit.prevent="addVariable">
<div class="field is-grouped">
<div class="control is-expanded">
<input class="input" type="text" placeholder="Key" v-model="form_key">
@@ -40,6 +40,12 @@
<div class="control is-expanded">
<input class="input" type="text" placeholder="Value" v-model="form_value">
</div>
<div class="control">
<button class="button is-danger" type="button"
v-tooltip="'Cancel'" @click="form_key=null; form_value=null; toggleForm=false">
<span class="icon"><i class="fas fa-cancel"></i></span>
</button>
</div>
<div class="control">
<button class="button is-primary" type="submit" :disabled="!form_key || !form_value">
<span class="icon"><i class="fas fa-save"></i></span>
@@ -61,8 +67,17 @@
</thead>
<tbody>
<tr v-for="env in envs" :key="env.key">
<td class="has-text-left">{{ env.key }}</td>
<td class="has-text-left">{{ env.value }}</td>
<td class="has-text-left">
{{ env.key }}
<div class="is-pulled-right" v-if="env.mask">
<span class="icon is-small has-tooltip" v-tooltip="'The value of this key is masked.'">
<i class="fas fa-lock"></i>
</span>
</div>
</td>
<td class="has-text-left" :class="{ 'is-masked': env.mask, 'is-unselectable': env.mask }">
{{ env.value }}
</td>
<td>
<div class="field is-grouped" style="justify-content: center">
<div class="control">
@@ -72,6 +87,13 @@
</span>
</button>
</div>
<div class="control" v-if="copyAPI">
<button class="button is-small is-warning" @click="copyValue(env)">
<span class="icon">
<i class="fas fa-copy"></i>
</span>
</button>
</div>
<div class="control">
<button class="button is-small is-danger" @click="deleteEnv(env)">
<span class="icon">
@@ -84,6 +106,11 @@
</tr>
</tbody>
</table>
<div class="is-hidden-mobile">
<Message message_class="is-info" title="Informational">
Some variables values are masked for security reasons. If you need to see the value, click on edit.
</Message>
</div>
</div>
</div>
</div>
@@ -91,6 +118,7 @@
<script setup>
import request from "~/utils/request.js";
import {awaitElement} from "~/utils/index.js";
useHead({title: 'Environment Variables'})
@@ -99,6 +127,7 @@ const toggleForm = ref(false)
const form_key = ref(null)
const form_value = ref(null)
const file = ref('.env')
const copyAPI = navigator.clipboard
const loadContent = async () => {
envs.value = []
@@ -126,7 +155,7 @@ const deleteEnv = async (env) => {
const addVariable = async () => {
const key = form_key.value.toUpperCase()
if (!key.startsWith('WS_')) {
alert('Key must start with WS_')
return
@@ -150,4 +179,19 @@ const editEnv = (env) => {
form_value.value = env.value
toggleForm.value = true
}
const copyValue = (env) => navigator.clipboard.writeText(env.value)
watch(toggleForm, (value) => {
if (!value) {
form_key.value = null
form_value.value = null
} else {
awaitElement('#env_page_title', (_, el) => el.scrollIntoView({
behavior: 'smooth',
block: 'start',
inline: 'nearest'
}))
}
});
</script>

View File

@@ -41,4 +41,22 @@ const humanFileSize = (bytes = 0, showUnit = true, decimals = 2, mod = 1000) =>
return `${(bytes / (mod ** factor)).toFixed(decimals)}${showUnit ? sz[factor] : ''}`;
}
export {ag_set, ag, humanFileSize}
const awaitElement = (sel, callback) => {
let interval = undefined;
let $elm = document.querySelector(sel)
if ($elm) {
return callback(sel, $elm);
}
interval = setInterval(() => {
let $elm = document.querySelector(sel);
if ($elm) {
clearInterval(interval);
callback(sel, $elm);
}
}, 200);
}
export {ag_set, ag, humanFileSize, awaitElement}

View File

@@ -17,6 +17,11 @@ final class Env
{
public const string URL = '%{api.prefix}/system/env';
private const array MASK = [
'WS_API_KEY',
'WS_CACHE_URL'
];
private EnvFile $envfile;
public function __construct()
@@ -43,6 +48,7 @@ final class Env
$response['data'][] = [
'key' => $key,
'value' => $val,
'mask' => in_array($key, self::MASK),
'urls' => [
'self' => (string)$request->getUri()->withPath(parseConfigValue(self::URL . '/' . $key)),
],