Skip to content

Commit

Permalink
Merge remote-tracking branch 'origin/develop' into develop
Browse files Browse the repository at this point in the history
  • Loading branch information
DanSheps committed Aug 30, 2021
2 parents ae42057 + 0884457 commit 069c7b7
Show file tree
Hide file tree
Showing 17 changed files with 208 additions and 217 deletions.
2 changes: 1 addition & 1 deletion netbox_secretstore/project-static/bundle.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ const options = {
minify: true,
sourcemap: true,
logLevel: 'error',
publicPath: '/static',
publicPath: '/static/netbox_secretstore',
};

/**
Expand Down
13 changes: 4 additions & 9 deletions netbox_secretstore/project-static/dist/secrets.js

Large diffs are not rendered by default.

6 changes: 3 additions & 3 deletions netbox_secretstore/project-static/dist/secrets.js.map

Large diffs are not rendered by default.

5 changes: 1 addition & 4 deletions netbox_secretstore/project-static/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -8,15 +8,12 @@
"typecheck": "tsc --noEmit"
},
"dependencies": {
"@mdi/font": "^5.9.55",
"@popperjs/core": "^2.9.2",
"@types/cookie": "^0.4.1",
"bootstrap": "^5.0.2",
"cookie": "^0.4.1",
"esbuild": "^0.12.17"
},
"devDependencies": {
"@types/bootstrap": "^5.0.12",
"@types/cookie": "^0.4.1",
"@typescript-eslint/eslint-plugin": "^4.17.0",
"@typescript-eslint/parser": "^4.17.0",
"eslint": "^7.22.0",
Expand Down
77 changes: 36 additions & 41 deletions netbox_secretstore/project-static/src/bs.ts
Original file line number Diff line number Diff line change
@@ -1,62 +1,57 @@
import { Toast } from "bootstrap";

type ToastLevel = "danger" | "warning" | "success" | "info";
type ToastLevel = 'danger' | 'warning' | 'success' | 'info';

export function createToast(
level: ToastLevel,
title: string,
message: string,
extra?: string
): Toast {
let iconName = "mdi-alert";
extra?: string,
): InstanceType<typeof window.Toast> {
let iconName = 'mdi-alert';
switch (level) {
case "warning":
iconName = "mdi-alert";
case "success":
iconName = "mdi-check-circle";
case "info":
iconName = "mdi-information";
case "danger":
iconName = "mdi-alert";
case 'warning':
iconName = 'mdi-alert';
case 'success':
iconName = 'mdi-check-circle';
case 'info':
iconName = 'mdi-information';
case 'danger':
iconName = 'mdi-alert';
}

const container = document.createElement("div");
container.setAttribute(
"class",
"toast-container position-fixed bottom-0 end-0 m-3"
);
const container = document.createElement('div');
container.setAttribute('class', 'toast-container position-fixed bottom-0 end-0 m-3');

const main = document.createElement("div");
main.setAttribute("class", `toast bg-${level}`);
main.setAttribute("role", "alert");
main.setAttribute("aria-live", "assertive");
main.setAttribute("aria-atomic", "true");
const main = document.createElement('div');
main.setAttribute('class', `toast bg-${level}`);
main.setAttribute('role', 'alert');
main.setAttribute('aria-live', 'assertive');
main.setAttribute('aria-atomic', 'true');

const header = document.createElement("div");
header.setAttribute("class", `toast-header bg-${level} text-body`);
const header = document.createElement('div');
header.setAttribute('class', `toast-header bg-${level} text-body`);

const icon = document.createElement("i");
icon.setAttribute("class", `mdi ${iconName}`);
const icon = document.createElement('i');
icon.setAttribute('class', `mdi ${iconName}`);

const titleElement = document.createElement("strong");
titleElement.setAttribute("class", "me-auto ms-1");
const titleElement = document.createElement('strong');
titleElement.setAttribute('class', 'me-auto ms-1');
titleElement.innerText = title;

const button = document.createElement("button");
button.setAttribute("type", "button");
button.setAttribute("class", "btn-close");
button.setAttribute("data-bs-dismiss", "toast");
button.setAttribute("aria-label", "Close");
const button = document.createElement('button');
button.setAttribute('type', 'button');
button.setAttribute('class', 'btn-close');
button.setAttribute('data-bs-dismiss', 'toast');
button.setAttribute('aria-label', 'Close');

const body = document.createElement("div");
body.setAttribute("class", "toast-body");
const body = document.createElement('div');
body.setAttribute('class', 'toast-body');

header.appendChild(icon);
header.appendChild(titleElement);

if (typeof extra !== "undefined") {
const extraElement = document.createElement("small");
extraElement.setAttribute("class", "text-muted");
if (typeof extra !== 'undefined') {
const extraElement = document.createElement('small');
extraElement.setAttribute('class', 'text-muted');
header.appendChild(extraElement);
}

Expand All @@ -69,6 +64,6 @@ export function createToast(
container.appendChild(main);
document.body.appendChild(container);

const toast = new Toast(main);
const toast = new window.Toast(main);
return toast;
}
5 changes: 5 additions & 0 deletions netbox_secretstore/project-static/src/global.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -30,3 +30,8 @@ type APIObjectBase = {
url: string;
[k: string]: JSONAble;
};

interface Window {
Modal: typeof import('bootstrap').Modal;
Toast: typeof import('bootstrap').Toast;
}
70 changes: 37 additions & 33 deletions netbox_secretstore/project-static/src/secrets.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
import { Modal } from 'bootstrap';
import { createToast } from './bs';
import { apiGetBase, apiPostForm, isApiError, hasError } from './util';
import { apiGetBase, apiPostForm, isApiError, isInputElement, hasError } from './util';

import type { APISecret, APIKeyPair } from './types';

Expand Down Expand Up @@ -44,6 +43,7 @@ function initGenerateKeyPair() {
}
});
}

/**
* Set the public key form field's value to the generated public key.
*/
Expand All @@ -54,8 +54,8 @@ function initGenerateKeyPair() {
publicKeyField.innerText = publicElem.value;
}
}
element.addEventListener('shown.bs.modal', handleOpen);
accept.addEventListener('click', handleAccept);
element.addEventListener('shown.bs.modal', () => handleOpen());
accept.addEventListener('click', () => handleAccept());
}

/**
Expand Down Expand Up @@ -88,19 +88,15 @@ function toggleSecretButtons(id: string, action: 'lock' | 'unlock') {
* Initialize Lock & Unlock button event listeners & callbacks.
*/
function initLockUnlock() {
const privateKeyModalElem = document.getElementById('privkey_modal');
if (privateKeyModalElem === null) {
return;
}
const privateKeyModal = new Modal(privateKeyModalElem);
const privateKeyModal = new window.Modal('#privkey_modal');

/**
* Unlock a secret, or prompt the user for their private key, if a session key is not available.
*
* @param id Secret ID
*/
function unlock(id: string | null) {
const target = document.getElementById(`secret_${id}`);
const target = document.getElementById(`secret_${id}`) as HTMLDivElement | HTMLInputElement;
if (typeof id === 'string' && id !== '') {
apiGetBase<APISecret>(`/api/plugins/netbox_secretstore/secrets/${id}`).then(data => {
if (!hasError(data)) {
Expand All @@ -111,7 +107,12 @@ function initLockUnlock() {
if (target !== null && plaintext !== null) {
// If `plaintext` is not null, we have the decrypted value. Set the target element's
// inner text to the decrypted value and toggle copy/lock button visibility.
target.innerText = plaintext;
if (isInputElement(target)) {
target.value = plaintext;
} else {
target.innerText = plaintext;
}

toggleSecretButtons(id, 'unlock');
} else {
// Otherwise, we do _not_ have the decrypted value and need to prompt the user for
Expand All @@ -134,17 +135,22 @@ function initLockUnlock() {
});
}
}

/**
* Lock a secret and toggle visibility of the unlock button.
* @param id Secret ID
*/
function lock(id: string | null) {
if (typeof id === 'string' && id !== '') {
const target = document.getElementById(`secret_${id}`);
if (target !== null) {
// Obscure the inner text of the secret element.
const target = document.getElementById(`secret_${id}`) as HTMLDivElement | HTMLInputElement;

// Obscure the inner text of the secret element.
if (isInputElement(target)) {
target.value = '********';
} else {
target.innerText = '********';
}

// Toggle visibility of the copy/lock/unlock buttons.
toggleSecretButtons(id, 'lock');
}
Expand Down Expand Up @@ -204,30 +210,28 @@ function initGetSessionKey() {
}
}

/**
* Initialize Secret Edit Form Handler.
*/
function initSecretsEdit() {
const privateKeyModalElem = document.getElementById('privkey_modal');
if (privateKeyModalElem === null) {
return;
const privateKeyModal = new window.Modal('#privkey_modal');

/**
* Check the cookie store for a `session_key`. If not present, prompt the user to submit their
* private key.
*/
function handleSubmit(event: Event): void {
if (document.cookie.indexOf('session_key') === -1) {
event.preventDefault();
privateKeyModal.show();
}
}
const privateKeyModal = new Modal(privateKeyModalElem);
let lastform = null

for (const element of document.querySelectorAll<HTMLElement>('.requires-session-key')) {
for (const element of document.querySelectorAll<HTMLInputElement>('.requires-session-key')) {
const form = element.closest<HTMLFormElement>('form');
if ( form === null ) {
return
}
if ( lastform === null || lastform !== form ) {
function handleSubmit(event: Event) {
if (document.cookie.indexOf('session_key') == -1) {
privateKeyModal.show();
event.preventDefault();
return false
}
}
form.addEventListener('submit', handleSubmit)
if (form !== null) {
form.addEventListener('submit', handleSubmit);
}
lastform = form;
}
}

Expand Down
9 changes: 9 additions & 0 deletions netbox_secretstore/project-static/src/util.ts
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,15 @@ export function hasError(data: Record<string, unknown>): data is ErrorBase {
return 'error' in data;
}

/**
* Type guard to determine if an element is an `HTMLInputElement`.
*
* @param element HTML Element.
*/
export function isInputElement(element: HTMLElement): element is HTMLInputElement {
return 'value' in element && 'required' in element;
}

/**
* Retrieve the CSRF token from cookie storage.
*/
Expand Down
10 changes: 0 additions & 10 deletions netbox_secretstore/project-static/yarn.lock
Original file line number Diff line number Diff line change
Expand Up @@ -52,11 +52,6 @@
resolved "https://registry.yarnpkg.com/@humanwhocodes/object-schema/-/object-schema-1.2.0.tgz#87de7af9c231826fdd68ac7258f77c429e0e5fcf"
integrity sha512-wdppn25U8z/2yiaT6YGquE6X8sSv7hNMWSXYSSU1jGv/yd6XqjXgTDJ8KP4NgjTXfJ3GbRjeeb8RTV7a/VpM+w==

"@mdi/font@^5.9.55":
version "5.9.55"
resolved "https://registry.yarnpkg.com/@mdi/font/-/font-5.9.55.tgz#41acd50b88073ded7095fc3029d8712b6e12f38e"
integrity sha512-jswRF6q3eq8NWpWiqct6q+6Fg/I7nUhrxYJfiEM8JJpap0wVJLQdbKtyS65GdlK7S7Ytnx3TTi/bmw+tBhkGmg==

"@nodelib/[email protected]":
version "2.1.5"
resolved "https://registry.yarnpkg.com/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz#7619c2eb21b25483f6d167548b4cfd5a7488c3d5"
Expand Down Expand Up @@ -346,11 +341,6 @@ balanced-match@^1.0.0:
resolved "https://registry.yarnpkg.com/balanced-match/-/balanced-match-1.0.2.tgz#e83e3a7e3f300b34cb9d87f615fa0cbf357690ee"
integrity sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==

bootstrap@^5.0.2:
version "5.0.2"
resolved "https://registry.yarnpkg.com/bootstrap/-/bootstrap-5.0.2.tgz#aff23d5e0e03c31255ad437530ee6556e78e728e"
integrity sha512-1Ge963tyEQWJJ+8qtXFU6wgmAVj9gweEjibUdbmcCEYsn38tVwRk8107rk2vzt6cfQcRr3SlZ8aQBqaD8aqf+Q==

brace-expansion@^1.1.7:
version "1.1.11"
resolved "https://registry.yarnpkg.com/brace-expansion/-/brace-expansion-1.1.11.tgz#3c7fcbf529d87226f3d2f52b966ff5271eb441dd"
Expand Down
13 changes: 4 additions & 9 deletions netbox_secretstore/static/netbox_secretstore/secrets.js

Large diffs are not rendered by default.

6 changes: 3 additions & 3 deletions netbox_secretstore/static/netbox_secretstore/secrets.js.map

Large diffs are not rendered by default.

Loading

0 comments on commit 069c7b7

Please sign in to comment.