Latest Threat Research:SANDWORM_MODE: Shai-Hulud-Style npm Worm Hijacks CI Workflows and Poisons AI Toolchains.Details
Socket
Book a DemoInstallSign in
Socket

lungo-cli

Package Overview
Dependencies
Maintainers
1
Versions
34
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

lungo-cli - npm Package Compare versions

Comparing version
0.5.8
to
0.5.9
+32
src/lungo_cli/resources/web/eslint.config.js
import js from "@eslint/js"
import ts from "typescript-eslint"
import svelte from "eslint-plugin-svelte"
import prettier from "eslint-config-prettier"
import globals from "globals"
export default [
js.configs.recommended,
...ts.configs.recommended,
...svelte.configs["flat/recommended"],
prettier,
...svelte.configs["flat/prettier"],
{
languageOptions: {
globals: {
...globals.browser,
...globals.node,
},
},
},
{
files: ["**/*.svelte"],
languageOptions: {
parserOptions: {
parser: ts.parser,
},
},
},
{
ignores: ["build/", ".svelte-kit/", "dist/"],
},
]
export default {
plugins: {
"tailwindcss/nesting": {},
tailwindcss: {},
autoprefixer: {},
},
}
export default {
useTabs: false,
semi: false,
singleQuote: false,
trailingComma: "es5",
printWidth: 120,
htmlWhitespaceSensitivity: "ignore",
plugins: ["prettier-plugin-svelte", "prettier-plugin-tailwindcss"],
overrides: [
{
files: "*.svelte",
options: {
parser: "svelte",
},
},
],
}
import typography from "@tailwindcss/typography"
import daisyui from "daisyui"
export default {
content: ["./src/**/*.{html,js,svelte,ts}"],
daisyui: {
logs: false,
themes: [
// prettier-ignore
{
light: {
"color-scheme": "light",
"primary": "#570DF8",
"primary-content": "#F6F6F6",
"secondary": "#F000B8",
"secondary-content": "#F6F6F6",
"accent": "#1ECEBC",
"accent-content": "#07312D",
"neutral": "#2B3440",
"neutral-content": "#D7DDE4",
"base-100": "#F5F5F5",
"base-200": "#EBEBEB",
"base-300": "#E0E0E0",
"base-content": "#1F2937",
},
dark: {
"color-scheme": "dark",
"primary": "#661AE6",
"primary-content": "#FFFFFF",
"secondary": "#D926AA",
"secondary-content": "#FFFFFF",
"accent": "#1FB2A5",
"accent-content": "#FFFFFF",
"neutral": "#2A323C",
"neutral-focus": "#242B33",
"neutral-content": "#A6ADBB",
"base-100": "#1D232A",
"base-200": "#191E24",
"base-300": "#15191E",
"base-content": "#A6ADBB",
}
},
"emerald",
"synthwave",
"lofi",
"dracula",
],
},
theme: {
extend: {},
},
plugins: [typography, daisyui],
}
+1
-1
Metadata-Version: 2.1
Name: lungo-cli
Version: 0.5.8
Version: 0.5.9
Summary: A user-friendly home lab setup designed for small-to-mid-scale on-premises hosting.

@@ -5,0 +5,0 @@ Home-page: https://github.com/raymond-u/lungo

@@ -6,3 +6,3 @@ [tool.black]

name = "lungo-cli"
version = "0.5.8"
version = "0.5.9"
description = "A user-friendly home lab setup designed for small-to-mid-scale on-premises hosting."

@@ -29,3 +29,3 @@ authors = ["raymond-u <36328498+raymond-u@users.noreply.github.com>"]

[tool.poetry.group.dev.dependencies]
black = "^24.4.2"
black = "^24.8.0"

@@ -38,3 +38,3 @@ [tool.poetry.group.docs]

mkdocs-glightbox = "^0.4.0"
mkdocs-material = "^9.5.30"
mkdocs-material = "^9.5.31"
mkdocs-typer = "^0.0.3"

@@ -41,0 +41,0 @@

@@ -155,2 +155,3 @@ import os

compose_services = extract_multiline_value_from_yaml(compose_content, "services")
compose_volumes = extract_multiline_value_from_yaml(compose_content, "volumes")
compose_secrets = extract_multiline_value_from_yaml(compose_content, "secrets")

@@ -168,2 +169,3 @@ nginx_site = self.file_utils.read_text(plugin_dir / "nginx" / "site.conf", not_exist_ok=True)

compose_services=compose_services,
compose_volumes=compose_volumes,
compose_secrets=compose_secrets,

@@ -170,0 +172,0 @@ nginx_site=nginx_site,

@@ -98,3 +98,3 @@ from datetime import timedelta

class Session(Base):
lifetime: timedelta = timedelta(days=1)
lifetime: timedelta = timedelta(days=2)

@@ -101,0 +101,0 @@

@@ -84,2 +84,3 @@ import re

compose_services: str
compose_volumes: str
compose_secrets: str

@@ -86,0 +87,0 @@ nginx_site: str

@@ -32,2 +32,3 @@ {% set directories = config.directories %}

volumes:
- '{{ plugin_name }}_home:/root/home'
- '{{ plugin.dirs.plugin_dir }}/config:/etc/filebrowser:ro'

@@ -51,1 +52,5 @@ - '{{ plugin.dirs.cache_dir }}:/var/log/filebrowser:rw'

restart: 'unless-stopped'
volumes:
{{ plugin_name }}_home:
name: {{ plugin_name }}_home

@@ -35,3 +35,3 @@ {% set plugin_name = plugin.manifest.name %}

location {{ plugin.web_prefix }}/api/public {
location ~* ^{{ plugin.web_prefix }}/(?:api/public|static/assets)/ {
include snippets/proxy.conf;

@@ -44,3 +44,4 @@ include snippets/auth.conf;

proxy_pass http://{{ plugin_name }};
error_page 480 = @{{ plugin_name }};
return 480;
}

@@ -47,0 +48,0 @@

@@ -9,3 +9,3 @@ from typing import Any, override

name="filebrowser",
version="0.3.1",
version="0.3.2",
descriptive_name="File Browser",

@@ -12,0 +12,0 @@ description="File Browser as a Lungo plugin.",

@@ -23,2 +23,3 @@ {% set directories = config.directories %}

volumes:
- '{{ plugin_name }}_home:/home'
- '{{ plugin.dirs.plugin_dir }}/config/config.py:/etc/jupyterhub/config.py:ro'

@@ -42,3 +43,3 @@ - '{{ plugin.dirs.plugin_dir }}/config/sudoers:/etc/sudoers:ro'

secrets:
- source: JUPYTERHUB_COOKIE_SECRET
- source: {{ plugin_name }}_cookie_secret
target: /etc/jupyterhub/cookie_secret

@@ -48,4 +49,8 @@

volumes:
{{ plugin_name }}_home:
name: {{ plugin_name }}_home
secrets:
JUPYTERHUB_COOKIE_SECRET:
{{ plugin_name }}_cookie_secret:
file: '{{ plugin.dirs.generated_dir }}/cookie_secret'
FROM docker.io/jupyterhub/jupyterhub:{{ plugin.custom.jupyterhub_version }}
RUN apt-get update && \
apt-get install -y sudo && \
apt-get install -y git-all less nano sudo vim && \
rm -rf /var/lib/apt/lists/* && \

@@ -5,0 +5,0 @@ python3 -m pip install --no-cache-dir --upgrade setuptools pip && \

@@ -15,3 +15,3 @@ from pathlib import Path

name="jupyterhub",
version="0.3.2",
version="0.3.3",
descriptive_name="JupyterHub",

@@ -43,3 +43,3 @@ description="JupyterHub as a Lungo plugin.",

"jupyterhub_password": self.settings.password or self.file_utils.read_text(self.password_file),
"jupyterhub_version": "4.1.5",
"jupyterhub_version": "4.1.6",
"jupyterlab_version": "4.2.4",

@@ -46,0 +46,0 @@ }

@@ -23,2 +23,3 @@ {% set directories = config.directories %}

volumes:
- '{{ plugin_name }}_home:/home'
- '{{ plugin.dirs.plugin_dir }}/config/rserver.conf:/etc/rstudio/rserver.conf:ro'

@@ -43,1 +44,5 @@ - '{{ plugin.dirs.plugin_dir }}/config/rsession.conf:/etc/rstudio/rsession.conf:ro'

restart: 'unless-stopped'
volumes:
{{ plugin_name }}_home:
name: {{ plugin_name }}_home
FROM docker.io/rocker/verse:{{ plugin.custom.rstudio_version }}
RUN apt-get update && \
apt-get install -y nano && \
rm -rf /var/lib/apt/lists/*
RUN \

@@ -3,0 +6,0 @@ {% for account in users.accounts %}

@@ -35,2 +35,14 @@ {% set plugin_name = plugin.manifest.name %}

location {{ plugin.web_prefix }}/rstudio/deferredjs/ {
include snippets/proxy.conf;
include snippets/auth.conf;
if ($arg_iframe = "") {
return 307 $http_x_forwarded_proto://$http_x_forwarded_host$escaped_uri?iframe=1&$args;
}
error_page 480 = @{{ plugin_name }};
return 480;
}
location @{{ plugin_name }} {

@@ -37,0 +49,0 @@ include snippets/proxy.conf;

@@ -15,3 +15,3 @@ from pathlib import Path

name="rstudio",
version="0.3.1",
version="0.3.2",
descriptive_name="RStudio",

@@ -18,0 +18,0 @@ description="RStudio as a Lungo plugin.",

@@ -19,3 +19,3 @@ from ipaddress import IPv4Network

name="xray",
version="0.3.2",
version="0.3.3",
descriptive_name="Xray",

@@ -49,3 +49,3 @@ description="Xray as a Lungo plugin.",

"xray_salt": salt,
"xray_version": "1.8.21",
"xray_version": "1.8.23",
}

@@ -52,0 +52,0 @@

@@ -220,5 +220,5 @@ ## Configuration file for general settings

# # Type: integer | string
# # Default: 'P1DT'
# # Default: 'P2D'
# # Required: no
# lifetime: 'P1DT'
# lifetime: 'P2D'

@@ -225,0 +225,0 @@ # =====

@@ -48,3 +48,3 @@ {% set accounts = users.accounts %}

secrets:
- source: NGINX_PRIVATE_KEY
- source: nginx_private_key
target: /etc/ssl/private/lungo.key

@@ -149,3 +149,3 @@

secrets:
- source: KRATOS_SECRETS
- source: kratos_secrets
target: /etc/kratos/secrets.yaml

@@ -236,4 +236,11 @@

volumes:
{% for plugin_output in plugin_outputs %}
{% if plugin_output.manifest.have_backend and plugins[plugin_output.manifest.name].enabled %}
{{ plugin_output.compose_volumes }}
{% endif %}
{% endfor %}
secrets:
NGINX_PRIVATE_KEY:
nginx_private_key:
file: >-

@@ -245,3 +252,3 @@ {% if network.https.tls %}

{% endif %}
KRATOS_SECRETS:
kratos_secrets:
file: '{{ app_dirs.generated_dir }}/kratos/secrets.yaml'

@@ -248,0 +255,0 @@ {% for plugin_output in plugin_outputs %}

@@ -1,2 +0,1 @@

Dockerfile
.dockerignore

@@ -6,7 +5,7 @@ .env

.gitignore
.eslintignore
.eslintrc.cjs
.prettierignore
.prettierrc
.svelte-kit
Dockerfile
eslint.config.js
assets

@@ -13,0 +12,0 @@ build

@@ -16,3 +16,3 @@ {

"openapi-fetch": "^0.9.7",
"set-cookie-parser": "^2.6.0"
"set-cookie-parser": "^2.7.0"
},

@@ -22,13 +22,12 @@ "devDependencies": {

"@sveltejs/enhanced-img": "^0.3.1",
"@sveltejs/kit": "^2.5.18",
"@sveltejs/kit": "^2.5.20",
"@sveltejs/vite-plugin-svelte": "^3.1.1",
"@tailwindcss/typography": "^0.5.13",
"@types/set-cookie-parser": "^2.4.10",
"@typescript-eslint/eslint-plugin": "^7.17.0",
"@typescript-eslint/parser": "^7.17.0",
"autoprefixer": "^10.4.19",
"autoprefixer": "^10.4.20",
"daisyui": "^4.12.10",
"eslint": "^8.57.0",
"eslint": "^9.8.0",
"eslint-config-prettier": "^9.1.0",
"eslint-plugin-svelte": "^2.43.0",
"globals": "^15.9.0",
"json-schema-to-typescript": "^15.0.0",

@@ -42,5 +41,6 @@ "openapi-typescript": "^6.7.6",

"svelte": "^4.2.18",
"svelte-check": "^3.8.4",
"svelte-check": "^3.8.5",
"tailwindcss": "^3.4.7",
"typescript": "^5.5.4",
"typescript-eslint": "^8.0.0",
"vite": "^5.3.5"

@@ -51,5 +51,5 @@ },

"node": ">=20.0.0",
"pnpm": "^8.0.0"
"pnpm": "^9.0.0"
},
"packageManager": "pnpm@8.15.9"
"packageManager": "pnpm@9.6.0"
}

@@ -1,12 +0,12 @@

<!DOCTYPE html>
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8" />
<link href="%sveltekit.assets%/favicon.png" rel="icon" />
<head>
<meta charset="utf-8" />
<link href="%sveltekit.assets%/favicon.png" rel="icon" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
%sveltekit.head%
</head>
<body data-sveltekit-preload-data="hover">
<div style="display: contents">%sveltekit.body%</div>
</body>
%sveltekit.head%
</head>
<body data-sveltekit-preload-data="hover">
<div style="display: contents">%sveltekit.body%</div>
</body>
</html>

@@ -50,3 +50,3 @@ <script lang="ts">

? primaryGroup
: nodes.find((node) => node.group !== "default")?.group ?? "default"
: (nodes.find((node) => node.group !== "default")?.group ?? "default")
let otherGroups: KratosComponents["schemas"]["uiNode"]["group"][]

@@ -53,0 +53,0 @@

@@ -44,2 +44,34 @@ <script lang="ts">

const patchRedirects = (parentNode: HTMLElement) => {
for (const childNode of parentNode.querySelectorAll("a, area, base, form")) {
// Do not use `instanceof` here because the element might be from a different global context
if (childNode.tagName === "A" || childNode.tagName === "AREA" || childNode.tagName === "BASE") {
const node = childNode as HTMLAnchorElement | HTMLAreaElement | HTMLBaseElement
if (isSameHost(node.href, $page.url.host)) {
node.target = "_self"
} else if (node.target === "_top") {
node.target = "_self"
}
} else if (childNode.tagName === "FORM") {
const node = childNode as HTMLFormElement
if (node.target === "_blank" || node.target === "_top") {
node.target = "_self"
}
}
if (childNode.tagName === "A") {
childNode.removeAttribute("referrerpolicy")
}
if (childNode.tagName === "A" || childNode.tagName === "AREA" || childNode.tagName === "FORM") {
const node = childNode as HTMLAnchorElement | HTMLAreaElement | HTMLFormElement
node.relList.remove("noreferrer")
}
}
}
let observer: MutationObserver
const handleLoad = (e: Event) => {

@@ -98,5 +130,3 @@ const iframe = e.target as HTMLIFrameElement

target = "_self"
}
if (target === "_top") {
} else if (target === "_top") {
target = "_self"

@@ -111,24 +141,9 @@ }

// Patch all links
for (const node of iframe.contentDocument!.querySelectorAll("a, area, base, form")) {
if (
node instanceof HTMLAnchorElement ||
node instanceof HTMLAreaElement ||
node instanceof HTMLBaseElement
) {
if (isSameHost(node.href, $page.url.host)) {
node.href = getModifiedUrl(node.href)
node.target = "_self"
}
// Patch all redirects
patchRedirects(iframe.contentDocument!.body)
observer.observe(iframe.contentDocument!.body, {
childList: true,
subtree: true,
})
if (node.target === "_top") {
node.target = "_self"
}
} else if (node instanceof HTMLFormElement) {
if (node.target === "_blank" || node.target === "_top") {
node.target = "_self"
}
}
}
// Patch the cookie setter

@@ -160,2 +175,17 @@ Object.defineProperty(iframe.contentDocument, "cookie", {

$currentIFrame = iFrame
observer = new MutationObserver((mutations: MutationRecord[]) => {
const parentElements = new Set<HTMLElement>()
for (const mutation of mutations) {
const parentElement = mutation.addedNodes[0]?.parentElement
if (parentElement) {
parentElements.add(parentElement)
}
}
for (const parentElement of parentElements) {
patchRedirects(parentElement)
}
})
iFrame!.addEventListener("load", handleLoad)

@@ -175,2 +205,3 @@ iFrame!.src = getModifiedUrl($page.url)

iFrame!.removeEventListener("load", handleLoad)
observer.disconnect()
$currentIFrame = undefined

@@ -177,0 +208,0 @@ }

@@ -87,3 +87,3 @@ import { type Cookies, error } from "@sveltejs/kit"

}
} catch (e) {
} catch {
error(500)

@@ -90,0 +90,0 @@ }

@@ -11,5 +11,7 @@ {

"sourceMap": true,
"strict": true
"strict": true,
"moduleResolution": "bundler"
}
// Path aliases are handled by https://kit.svelte.dev/docs/configuration#alias
// except $lib which is handled by https://kit.svelte.dev/docs/configuration#files
//

@@ -16,0 +18,0 @@ // If you want to overwrite includes/excludes, make sure to copy over the relevant includes/excludes

Sorry, the diff of this file is not supported yet

module.exports = {
root: true,
extends: [
"eslint:recommended",
"plugin:@typescript-eslint/recommended",
"plugin:svelte/recommended",
"prettier",
],
parser: "@typescript-eslint/parser",
plugins: ["@typescript-eslint"],
parserOptions: {
sourceType: "module",
ecmaVersion: 2020,
extraFileExtensions: [".svelte"],
},
env: {
browser: true,
es2017: true,
node: true,
},
overrides: [
{
files: ["*.svelte"],
parser: "svelte-eslint-parser",
parserOptions: {
parser: "@typescript-eslint/parser",
},
},
],
}
{
"useTabs": false,
"semi": false,
"singleQuote": false,
"trailingComma": "es5",
"printWidth": 120,
"htmlWhitespaceSensitivity": "ignore",
"plugins": [
"prettier-plugin-svelte",
"prettier-plugin-tailwindcss"
],
"overrides": [
{
"files": "*.svelte",
"options": {
"parser": "svelte"
}
}
]
}
const nesting = require("tailwindcss/nesting")
const tailwindcss = require("tailwindcss")
const autoprefixer = require("autoprefixer")
const config = {
plugins: [
nesting,
tailwindcss(),
autoprefixer,
],
}
module.exports = config
const typography = require("@tailwindcss/typography")
const daisyui = require("daisyui")
/** @type {import("tailwindcss").Config}*/
const config = {
content: ["./src/**/*.{html,js,svelte,ts}"],
daisyui: {
logs: false,
themes: [
{
light: {
"color-scheme": "light",
"primary": "#570DF8",
"primary-content": "#F6F6F6",
"secondary": "#F000B8",
"secondary-content": "#F6F6F6",
"accent": "#1ECEBC",
"accent-content": "#07312D",
"neutral": "#2B3440",
"neutral-content": "#D7DDE4",
"base-100": "#F5F5F5",
"base-200": "#EBEBEB",
"base-300": "#E0E0E0",
"base-content": "#1F2937",
},
dark: {
"color-scheme": "dark",
"primary": "#661AE6",
"primary-content": "#FFFFFF",
"secondary": "#D926AA",
"secondary-content": "#FFFFFF",
"accent": "#1FB2A5",
"accent-content": "#FFFFFF",
"neutral": "#2A323C",
"neutral-focus": "#242B33",
"neutral-content": "#A6ADBB",
"base-100": "#1D232A",
"base-200": "#191E24",
"base-300": "#15191E",
"base-content": "#A6ADBB",
}
},
"emerald",
"synthwave",
"lofi",
"dracula",
],
},
theme: {
extend: {},
},
plugins: [
typography,
daisyui,
],
}
module.exports = config

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is too big to display

Sorry, the diff of this file is not supported yet