feat: Able to modify database passwords
This commit is contained in:
3
src/app.d.ts
vendored
3
src/app.d.ts
vendored
@@ -15,6 +15,9 @@ declare namespace App {
|
|||||||
readOnly: boolean;
|
readOnly: boolean;
|
||||||
source: string;
|
source: string;
|
||||||
settings: string;
|
settings: string;
|
||||||
|
database: Record<string, any>;
|
||||||
|
versions: string;
|
||||||
|
privatePort: string;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -56,7 +56,7 @@ export const supportedDatabaseTypesAndVersions = [
|
|||||||
name: 'postgresql',
|
name: 'postgresql',
|
||||||
fancyName: 'PostgreSQL',
|
fancyName: 'PostgreSQL',
|
||||||
baseImage: 'bitnami/postgresql',
|
baseImage: 'bitnami/postgresql',
|
||||||
versions: ['14.2', '13.6', '12.10', '11.15', '10.20']
|
versions: ['14.2.0', '13.6.0', '12.10.0 ', '11.15.0', '10.20.0']
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: 'redis',
|
name: 'redis',
|
||||||
|
@@ -137,3 +137,37 @@ export async function stopDatabase(database) {
|
|||||||
}
|
}
|
||||||
return everStarted;
|
return everStarted;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export async function updatePasswordInDb(database, user, newPassword) {
|
||||||
|
const {
|
||||||
|
id,
|
||||||
|
type,
|
||||||
|
rootUser,
|
||||||
|
rootUserPassword,
|
||||||
|
dbUser,
|
||||||
|
dbUserPassword,
|
||||||
|
defaultDatabase,
|
||||||
|
destinationDockerId,
|
||||||
|
destinationDocker: { engine }
|
||||||
|
} = database;
|
||||||
|
if (destinationDockerId) {
|
||||||
|
const host = getEngine(engine);
|
||||||
|
if (type === 'mysql') {
|
||||||
|
await asyncExecShell(
|
||||||
|
`DOCKER_HOST=${host} docker exec ${id} mysql -u ${rootUser} -p${rootUserPassword} -e \"ALTER USER '${user}'@'%' IDENTIFIED WITH caching_sha2_password BY '${newPassword}';\"`
|
||||||
|
);
|
||||||
|
} else if (type === 'postgresql') {
|
||||||
|
await asyncExecShell(
|
||||||
|
`DOCKER_HOST=${host} docker exec ${id} psql postgresql://${dbUser}:${dbUserPassword}@${id}:5432/${defaultDatabase} -c "ALTER role ${user} WITH PASSWORD '${newPassword}'"`
|
||||||
|
);
|
||||||
|
} else if (type === 'mongodb') {
|
||||||
|
await asyncExecShell(
|
||||||
|
`DOCKER_HOST=${host} docker exec ${id} mongo 'mongodb://${rootUser}:${rootUserPassword}@${id}:27017/admin?readPreference=primary&ssl=false' --eval "db.changeUserPassword('${user}','${newPassword}')"`
|
||||||
|
);
|
||||||
|
} else if (type === 'redis') {
|
||||||
|
await asyncExecShell(
|
||||||
|
`DOCKER_HOST=${host} docker exec ${id} redis-cli -u redis://${dbUserPassword}@${id}:6379 --raw CONFIG SET requirepass ${newPassword}`
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@@ -44,9 +44,7 @@ export async function configureDestinationForDatabase({ id, destinationId }) {
|
|||||||
const host = getEngine(engine);
|
const host = getEngine(engine);
|
||||||
if (type && version) {
|
if (type && version) {
|
||||||
const baseImage = getDatabaseImage(type);
|
const baseImage = getDatabaseImage(type);
|
||||||
asyncExecShell(
|
asyncExecShell(`DOCKER_HOST=${host} docker pull ${baseImage}:${version}`);
|
||||||
`DOCKER_HOST=${host} docker pull ${baseImage}:${version} && echo "FROM ${baseImage}:${version}" | docker build --label coolify.image="true" -t "${baseImage}:${version}" -`
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -2,6 +2,8 @@
|
|||||||
export let database;
|
export let database;
|
||||||
export let privatePort;
|
export let privatePort;
|
||||||
export let settings;
|
export let settings;
|
||||||
|
export let isRunning;
|
||||||
|
|
||||||
import { page, session } from '$app/stores';
|
import { page, session } from '$app/stores';
|
||||||
import CopyPasswordField from '$lib/components/CopyPasswordField.svelte';
|
import CopyPasswordField from '$lib/components/CopyPasswordField.svelte';
|
||||||
import Setting from '$lib/components/Setting.svelte';
|
import Setting from '$lib/components/Setting.svelte';
|
||||||
@@ -15,24 +17,36 @@
|
|||||||
import { browser } from '$app/env';
|
import { browser } from '$app/env';
|
||||||
import { post } from '$lib/api';
|
import { post } from '$lib/api';
|
||||||
import { getDomain } from '$lib/components/common';
|
import { getDomain } from '$lib/components/common';
|
||||||
|
import { toast } from '@zerodevx/svelte-toast';
|
||||||
|
|
||||||
const { id } = $page.params;
|
const { id } = $page.params;
|
||||||
|
|
||||||
let loading = false;
|
let loading = false;
|
||||||
|
let publicLoading = false;
|
||||||
|
|
||||||
let isPublic = database.settings.isPublic || false;
|
let isPublic = database.settings.isPublic || false;
|
||||||
let appendOnly = database.settings.appendOnly;
|
let appendOnly = database.settings.appendOnly;
|
||||||
|
|
||||||
let databaseDefault = database.defaultDatabase;
|
let databaseDefault;
|
||||||
let databaseDbUser = database.dbUser;
|
let databaseDbUser;
|
||||||
let databaseDbUserPassword = database.dbUserPassword;
|
let databaseDbUserPassword;
|
||||||
if (database.type === 'mongodb') {
|
|
||||||
databaseDefault = '?readPreference=primary&ssl=false';
|
generateDbDetails();
|
||||||
databaseDbUser = database.rootUser;
|
|
||||||
databaseDbUserPassword = database.rootUserPassword;
|
function generateDbDetails() {
|
||||||
} else if (database.type === 'redis') {
|
databaseDefault = database.defaultDatabase;
|
||||||
databaseDefault = '';
|
databaseDbUser = database.dbUser;
|
||||||
databaseDbUser = '';
|
databaseDbUserPassword = database.dbUserPassword;
|
||||||
|
if (database.type === 'mongodb') {
|
||||||
|
databaseDefault = '?readPreference=primary&ssl=false';
|
||||||
|
databaseDbUser = database.rootUser;
|
||||||
|
databaseDbUserPassword = database.rootUserPassword;
|
||||||
|
} else if (database.type === 'redis') {
|
||||||
|
databaseDefault = '';
|
||||||
|
databaseDbUser = '';
|
||||||
|
}
|
||||||
}
|
}
|
||||||
let databaseUrl = generateUrl();
|
$: databaseUrl = generateUrl();
|
||||||
|
|
||||||
function generateUrl() {
|
function generateUrl() {
|
||||||
return browser
|
return browser
|
||||||
@@ -49,28 +63,46 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
async function changeSettings(name) {
|
async function changeSettings(name) {
|
||||||
|
if (publicLoading || !isRunning) return;
|
||||||
|
publicLoading = true;
|
||||||
|
let data = {
|
||||||
|
isPublic,
|
||||||
|
appendOnly
|
||||||
|
};
|
||||||
if (name === 'isPublic') {
|
if (name === 'isPublic') {
|
||||||
isPublic = !isPublic;
|
data.isPublic = !isPublic;
|
||||||
}
|
}
|
||||||
if (name === 'appendOnly') {
|
if (name === 'appendOnly') {
|
||||||
appendOnly = !appendOnly;
|
data.appendOnly = !appendOnly;
|
||||||
}
|
}
|
||||||
try {
|
try {
|
||||||
const { publicPort } = await post(`/databases/${id}/settings.json`, { isPublic, appendOnly });
|
const { publicPort } = await post(`/databases/${id}/settings.json`, {
|
||||||
|
isPublic: data.isPublic,
|
||||||
|
appendOnly: data.appendOnly
|
||||||
|
});
|
||||||
|
isPublic = data.isPublic;
|
||||||
|
appendOnly = data.appendOnly;
|
||||||
|
databaseUrl = generateUrl();
|
||||||
if (isPublic) {
|
if (isPublic) {
|
||||||
database.publicPort = publicPort;
|
database.publicPort = publicPort;
|
||||||
}
|
}
|
||||||
databaseUrl = generateUrl();
|
|
||||||
} catch ({ error }) {
|
} catch ({ error }) {
|
||||||
return errorNotification(error);
|
return errorNotification(error);
|
||||||
|
} finally {
|
||||||
|
publicLoading = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
async function handleSubmit() {
|
async function handleSubmit() {
|
||||||
try {
|
try {
|
||||||
await post(`/databases/${id}.json`, { ...database });
|
loading = true;
|
||||||
return window.location.reload();
|
await post(`/databases/${id}.json`, { ...database, isRunning });
|
||||||
|
generateDbDetails();
|
||||||
|
databaseUrl = generateUrl();
|
||||||
|
toast.push('Settings saved.');
|
||||||
} catch ({ error }) {
|
} catch ({ error }) {
|
||||||
return errorNotification(error);
|
return errorNotification(error);
|
||||||
|
} finally {
|
||||||
|
loading = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
@@ -142,21 +174,21 @@
|
|||||||
readonly
|
readonly
|
||||||
disabled
|
disabled
|
||||||
name="publicPort"
|
name="publicPort"
|
||||||
value={isPublic ? database.publicPort : privatePort}
|
value={publicLoading ? 'Loading...' : isPublic ? database.publicPort : privatePort}
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="grid grid-flow-row gap-2">
|
<div class="grid grid-flow-row gap-2">
|
||||||
{#if database.type === 'mysql'}
|
{#if database.type === 'mysql'}
|
||||||
<MySql bind:database />
|
<MySql bind:database {isRunning} />
|
||||||
{:else if database.type === 'postgresql'}
|
{:else if database.type === 'postgresql'}
|
||||||
<PostgreSql bind:database />
|
<PostgreSql bind:database {isRunning} />
|
||||||
{:else if database.type === 'mongodb'}
|
{:else if database.type === 'mongodb'}
|
||||||
<MongoDb {database} />
|
<MongoDb bind:database {isRunning} />
|
||||||
{:else if database.type === 'redis'}
|
{:else if database.type === 'redis'}
|
||||||
<Redis {database} />
|
<Redis bind:database {isRunning} />
|
||||||
{:else if database.type === 'couchdb'}
|
{:else if database.type === 'couchdb'}
|
||||||
<CouchDb bind:database />
|
<CouchDb {database} />
|
||||||
{/if}
|
{/if}
|
||||||
<div class="grid grid-cols-2 items-center px-10 pb-8">
|
<div class="grid grid-cols-2 items-center px-10 pb-8">
|
||||||
<label for="url" class="text-base font-bold text-stone-100">Connection String</label>
|
<label for="url" class="text-base font-bold text-stone-100">Connection String</label>
|
||||||
@@ -168,7 +200,7 @@
|
|||||||
name="url"
|
name="url"
|
||||||
readonly
|
readonly
|
||||||
disabled
|
disabled
|
||||||
value={databaseUrl}
|
value={publicLoading || loading ? 'Loading...' : databaseUrl}
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@@ -179,10 +211,12 @@
|
|||||||
<div class="px-10 pb-10">
|
<div class="px-10 pb-10">
|
||||||
<div class="grid grid-cols-2 items-center">
|
<div class="grid grid-cols-2 items-center">
|
||||||
<Setting
|
<Setting
|
||||||
|
loading={publicLoading}
|
||||||
bind:setting={isPublic}
|
bind:setting={isPublic}
|
||||||
on:click={() => changeSettings('isPublic')}
|
on:click={() => changeSettings('isPublic')}
|
||||||
title="Set it public"
|
title="Set it public"
|
||||||
description="Your database will be reachable over the internet. <br>Take security seriously in this case!"
|
description="Your database will be reachable over the internet. <br>Take security seriously in this case!"
|
||||||
|
disabled={!isRunning}
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
{#if database.type === 'redis'}
|
{#if database.type === 'redis'}
|
||||||
|
@@ -1,6 +1,8 @@
|
|||||||
<script>
|
<script>
|
||||||
export let database;
|
export let database;
|
||||||
|
export let isRunning;
|
||||||
import CopyPasswordField from '$lib/components/CopyPasswordField.svelte';
|
import CopyPasswordField from '$lib/components/CopyPasswordField.svelte';
|
||||||
|
import Explainer from '$lib/components/Explainer.svelte';
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<div class="flex space-x-1 py-5 font-bold">
|
<div class="flex space-x-1 py-5 font-bold">
|
||||||
@@ -21,13 +23,14 @@
|
|||||||
<div class="grid grid-cols-2 items-center">
|
<div class="grid grid-cols-2 items-center">
|
||||||
<label for="rootUserPassword" class="text-base font-bold text-stone-100">Root's Password</label>
|
<label for="rootUserPassword" class="text-base font-bold text-stone-100">Root's Password</label>
|
||||||
<CopyPasswordField
|
<CopyPasswordField
|
||||||
|
disabled={!isRunning}
|
||||||
|
readonly={!isRunning}
|
||||||
placeholder="Generated automatically after start"
|
placeholder="Generated automatically after start"
|
||||||
isPasswordField={true}
|
isPasswordField={true}
|
||||||
readonly
|
|
||||||
disabled
|
|
||||||
id="rootUserPassword"
|
id="rootUserPassword"
|
||||||
name="rootUserPassword"
|
name="rootUserPassword"
|
||||||
value={database.rootUserPassword}
|
bind:value={database.rootUserPassword}
|
||||||
/>
|
/>
|
||||||
|
<Explainer text="Could be changed while the database is running." />
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
@@ -1,6 +1,8 @@
|
|||||||
<script>
|
<script>
|
||||||
export let database;
|
export let database;
|
||||||
|
export let isRunning;
|
||||||
import CopyPasswordField from '$lib/components/CopyPasswordField.svelte';
|
import CopyPasswordField from '$lib/components/CopyPasswordField.svelte';
|
||||||
|
import Explainer from '$lib/components/Explainer.svelte';
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<div class="flex space-x-1 py-5 font-bold">
|
<div class="flex space-x-1 py-5 font-bold">
|
||||||
@@ -33,14 +35,15 @@
|
|||||||
<div class="grid grid-cols-2 items-center">
|
<div class="grid grid-cols-2 items-center">
|
||||||
<label for="dbUserPassword" class="text-base font-bold text-stone-100">Password</label>
|
<label for="dbUserPassword" class="text-base font-bold text-stone-100">Password</label>
|
||||||
<CopyPasswordField
|
<CopyPasswordField
|
||||||
readonly
|
disabled={!isRunning}
|
||||||
disabled
|
readonly={!isRunning}
|
||||||
placeholder="Generated automatically after start"
|
placeholder="Generated automatically after start"
|
||||||
isPasswordField
|
isPasswordField
|
||||||
id="dbUserPassword"
|
id="dbUserPassword"
|
||||||
name="dbUserPassword"
|
name="dbUserPassword"
|
||||||
value={database.dbUserPassword}
|
bind:value={database.dbUserPassword}
|
||||||
/>
|
/>
|
||||||
|
<Explainer text="Could be changed while the database is running." />
|
||||||
</div>
|
</div>
|
||||||
<div class="grid grid-cols-2 items-center">
|
<div class="grid grid-cols-2 items-center">
|
||||||
<label for="rootUser" class="text-base font-bold text-stone-100">Root User</label>
|
<label for="rootUser" class="text-base font-bold text-stone-100">Root User</label>
|
||||||
@@ -56,13 +59,14 @@
|
|||||||
<div class="grid grid-cols-2 items-center">
|
<div class="grid grid-cols-2 items-center">
|
||||||
<label for="rootUserPassword" class="text-base font-bold text-stone-100">Root's Password</label>
|
<label for="rootUserPassword" class="text-base font-bold text-stone-100">Root's Password</label>
|
||||||
<CopyPasswordField
|
<CopyPasswordField
|
||||||
readonly
|
disabled={!isRunning}
|
||||||
disabled
|
readonly={!isRunning}
|
||||||
placeholder="Generated automatically after start"
|
placeholder="Generated automatically after start"
|
||||||
isPasswordField
|
isPasswordField
|
||||||
id="rootUserPassword"
|
id="rootUserPassword"
|
||||||
name="rootUserPassword"
|
name="rootUserPassword"
|
||||||
value={database.rootUserPassword}
|
bind:value={database.rootUserPassword}
|
||||||
/>
|
/>
|
||||||
|
<Explainer text="Could be changed while the database is running." />
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
@@ -1,6 +1,8 @@
|
|||||||
<script>
|
<script>
|
||||||
export let database;
|
export let database;
|
||||||
|
export let isRunning;
|
||||||
import CopyPasswordField from '$lib/components/CopyPasswordField.svelte';
|
import CopyPasswordField from '$lib/components/CopyPasswordField.svelte';
|
||||||
|
import Explainer from '$lib/components/Explainer.svelte';
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<div class="flex space-x-1 py-5 font-bold">
|
<div class="flex space-x-1 py-5 font-bold">
|
||||||
@@ -33,13 +35,14 @@
|
|||||||
<div class="grid grid-cols-2 items-center">
|
<div class="grid grid-cols-2 items-center">
|
||||||
<label for="dbUserPassword" class="text-base font-bold text-stone-100">Password</label>
|
<label for="dbUserPassword" class="text-base font-bold text-stone-100">Password</label>
|
||||||
<CopyPasswordField
|
<CopyPasswordField
|
||||||
readonly
|
disabled={!isRunning}
|
||||||
disabled
|
readonly={!isRunning}
|
||||||
placeholder="Generated automatically after start"
|
placeholder="Generated automatically after start"
|
||||||
isPasswordField
|
isPasswordField
|
||||||
id="dbUserPassword"
|
id="dbUserPassword"
|
||||||
name="dbUserPassword"
|
name="dbUserPassword"
|
||||||
value={database.dbUserPassword}
|
bind:value={database.dbUserPassword}
|
||||||
/>
|
/>
|
||||||
|
<Explainer text="Could be changed while the database is running." />
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
@@ -1,6 +1,8 @@
|
|||||||
<script>
|
<script>
|
||||||
export let database;
|
export let database;
|
||||||
|
export let isRunning;
|
||||||
import CopyPasswordField from '$lib/components/CopyPasswordField.svelte';
|
import CopyPasswordField from '$lib/components/CopyPasswordField.svelte';
|
||||||
|
import Explainer from '$lib/components/Explainer.svelte';
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<div class="flex space-x-1 py-5 font-bold">
|
<div class="flex space-x-1 py-5 font-bold">
|
||||||
@@ -10,40 +12,14 @@
|
|||||||
<div class="grid grid-cols-2 items-center">
|
<div class="grid grid-cols-2 items-center">
|
||||||
<label for="dbUserPassword" class="text-base font-bold text-stone-100">Password</label>
|
<label for="dbUserPassword" class="text-base font-bold text-stone-100">Password</label>
|
||||||
<CopyPasswordField
|
<CopyPasswordField
|
||||||
disabled
|
disabled={!isRunning}
|
||||||
readonly
|
readonly={!isRunning}
|
||||||
placeholder="Generated automatically after start"
|
placeholder="Generated automatically after start"
|
||||||
isPasswordField
|
isPasswordField
|
||||||
id="dbUserPassword"
|
id="dbUserPassword"
|
||||||
name="dbUserPassword"
|
name="dbUserPassword"
|
||||||
value={database.dbUserPassword}
|
bind:value={database.dbUserPassword}
|
||||||
/>
|
/>
|
||||||
|
<Explainer text="Could be changed while the database is running." />
|
||||||
</div>
|
</div>
|
||||||
<!-- <div class="grid grid-cols-3 items-center">
|
|
||||||
<label for="rootUser">Root User</label>
|
|
||||||
<div class="col-span-2 ">
|
|
||||||
<CopyPasswordField
|
|
||||||
disabled
|
|
||||||
readonly
|
|
||||||
placeholder="Generated automatically after start"
|
|
||||||
id="rootUser"
|
|
||||||
name="rootUser"
|
|
||||||
value={database.rootUser}
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="grid grid-cols-3 items-center">
|
|
||||||
<label for="rootUserPassword">Root's Password</label>
|
|
||||||
<div class="col-span-2 ">
|
|
||||||
<CopyPasswordField
|
|
||||||
disabled
|
|
||||||
readonly
|
|
||||||
placeholder="Generated automatically after start"
|
|
||||||
isPasswordField
|
|
||||||
id="rootUserPassword"
|
|
||||||
name="rootUserPassword"
|
|
||||||
value={database.rootUserPassword}
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
</div> -->
|
|
||||||
</div>
|
</div>
|
||||||
|
@@ -15,7 +15,7 @@
|
|||||||
const endpoint = `/databases/${params.id}.json`;
|
const endpoint = `/databases/${params.id}.json`;
|
||||||
const res = await fetch(endpoint);
|
const res = await fetch(endpoint);
|
||||||
if (res.ok) {
|
if (res.ok) {
|
||||||
const { database, state, versions, privatePort, settings } = await res.json();
|
const { database, isRunning, versions, privatePort, settings } = await res.json();
|
||||||
if (!database || Object.entries(database).length === 0) {
|
if (!database || Object.entries(database).length === 0) {
|
||||||
return {
|
return {
|
||||||
status: 302,
|
status: 302,
|
||||||
@@ -35,13 +35,13 @@
|
|||||||
return {
|
return {
|
||||||
props: {
|
props: {
|
||||||
database,
|
database,
|
||||||
state,
|
isRunning,
|
||||||
versions,
|
versions,
|
||||||
privatePort
|
privatePort
|
||||||
},
|
},
|
||||||
stuff: {
|
stuff: {
|
||||||
database,
|
database,
|
||||||
state,
|
isRunning,
|
||||||
versions,
|
versions,
|
||||||
privatePort,
|
privatePort,
|
||||||
settings
|
settings
|
||||||
@@ -65,7 +65,7 @@
|
|||||||
import { goto } from '$app/navigation';
|
import { goto } from '$app/navigation';
|
||||||
|
|
||||||
export let database;
|
export let database;
|
||||||
export let state;
|
export let isRunning;
|
||||||
let loading = false;
|
let loading = false;
|
||||||
|
|
||||||
async function deleteDatabase() {
|
async function deleteDatabase() {
|
||||||
@@ -91,8 +91,6 @@
|
|||||||
return window.location.reload();
|
return window.location.reload();
|
||||||
} catch ({ error }) {
|
} catch ({ error }) {
|
||||||
return errorNotification(error);
|
return errorNotification(error);
|
||||||
} finally {
|
|
||||||
loading = false;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -103,8 +101,6 @@
|
|||||||
return window.location.reload();
|
return window.location.reload();
|
||||||
} catch ({ error }) {
|
} catch ({ error }) {
|
||||||
return errorNotification(error);
|
return errorNotification(error);
|
||||||
} finally {
|
|
||||||
loading = false;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
@@ -114,7 +110,7 @@
|
|||||||
<Loading fullscreen cover />
|
<Loading fullscreen cover />
|
||||||
{:else}
|
{:else}
|
||||||
{#if database.type && database.destinationDockerId && database.version && database.defaultDatabase}
|
{#if database.type && database.destinationDockerId && database.version && database.defaultDatabase}
|
||||||
{#if state === 'running'}
|
{#if isRunning}
|
||||||
<button
|
<button
|
||||||
on:click={stopDatabase}
|
on:click={stopDatabase}
|
||||||
title="Stop database"
|
title="Stop database"
|
||||||
@@ -140,7 +136,7 @@
|
|||||||
<rect x="14" y="5" width="4" height="14" rx="1" />
|
<rect x="14" y="5" width="4" height="14" rx="1" />
|
||||||
</svg>
|
</svg>
|
||||||
</button>
|
</button>
|
||||||
{:else if state === 'not started'}
|
{:else}
|
||||||
<button
|
<button
|
||||||
on:click={startDatabase}
|
on:click={startDatabase}
|
||||||
title="Start database"
|
title="Start database"
|
||||||
|
@@ -1,6 +1,11 @@
|
|||||||
import { asyncExecShell, getEngine, getUserDetails } from '$lib/common';
|
import { asyncExecShell, getEngine, getUserDetails } from '$lib/common';
|
||||||
import * as db from '$lib/database';
|
import * as db from '$lib/database';
|
||||||
import { generateDatabaseConfiguration, getVersions, ErrorHandler } from '$lib/database';
|
import {
|
||||||
|
generateDatabaseConfiguration,
|
||||||
|
getVersions,
|
||||||
|
ErrorHandler,
|
||||||
|
updatePasswordInDb
|
||||||
|
} from '$lib/database';
|
||||||
import type { RequestHandler } from '@sveltejs/kit';
|
import type { RequestHandler } from '@sveltejs/kit';
|
||||||
|
|
||||||
export const get: RequestHandler = async (event) => {
|
export const get: RequestHandler = async (event) => {
|
||||||
@@ -12,7 +17,7 @@ export const get: RequestHandler = async (event) => {
|
|||||||
const database = await db.getDatabase({ id, teamId });
|
const database = await db.getDatabase({ id, teamId });
|
||||||
const { destinationDockerId, destinationDocker } = database;
|
const { destinationDockerId, destinationDocker } = database;
|
||||||
|
|
||||||
let state = 'not started';
|
let isRunning = false;
|
||||||
if (destinationDockerId) {
|
if (destinationDockerId) {
|
||||||
const host = getEngine(destinationDocker.engine);
|
const host = getEngine(destinationDocker.engine);
|
||||||
|
|
||||||
@@ -22,7 +27,7 @@ export const get: RequestHandler = async (event) => {
|
|||||||
);
|
);
|
||||||
|
|
||||||
if (JSON.parse(stdout).Running) {
|
if (JSON.parse(stdout).Running) {
|
||||||
state = 'running';
|
isRunning = true;
|
||||||
}
|
}
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
//
|
//
|
||||||
@@ -34,7 +39,7 @@ export const get: RequestHandler = async (event) => {
|
|||||||
body: {
|
body: {
|
||||||
privatePort: configuration?.privatePort,
|
privatePort: configuration?.privatePort,
|
||||||
database,
|
database,
|
||||||
state,
|
isRunning,
|
||||||
versions: getVersions(database.type),
|
versions: getVersions(database.type),
|
||||||
settings
|
settings
|
||||||
}
|
}
|
||||||
@@ -48,10 +53,26 @@ export const post: RequestHandler = async (event) => {
|
|||||||
const { teamId, status, body } = await getUserDetails(event);
|
const { teamId, status, body } = await getUserDetails(event);
|
||||||
if (status === 401) return { status, body };
|
if (status === 401) return { status, body };
|
||||||
const { id } = event.params;
|
const { id } = event.params;
|
||||||
const { name, defaultDatabase, dbUser, dbUserPassword, rootUser, rootUserPassword, version } =
|
const {
|
||||||
await event.request.json();
|
name,
|
||||||
|
defaultDatabase,
|
||||||
|
dbUser,
|
||||||
|
dbUserPassword,
|
||||||
|
rootUser,
|
||||||
|
rootUserPassword,
|
||||||
|
version,
|
||||||
|
isRunning
|
||||||
|
} = await event.request.json();
|
||||||
|
|
||||||
try {
|
try {
|
||||||
|
const database = await db.getDatabase({ id, teamId });
|
||||||
|
if (isRunning) {
|
||||||
|
if (database.dbUserPassword !== dbUserPassword) {
|
||||||
|
await updatePasswordInDb(database, dbUser, dbUserPassword);
|
||||||
|
} else if (database.rootUserPassword !== rootUserPassword) {
|
||||||
|
await updatePasswordInDb(database, rootUser, rootUserPassword);
|
||||||
|
}
|
||||||
|
}
|
||||||
await db.updateDatabase({
|
await db.updateDatabase({
|
||||||
id,
|
id,
|
||||||
name,
|
name,
|
||||||
|
@@ -8,7 +8,8 @@
|
|||||||
database: stuff.database,
|
database: stuff.database,
|
||||||
versions: stuff.versions,
|
versions: stuff.versions,
|
||||||
privatePort: stuff.privatePort,
|
privatePort: stuff.privatePort,
|
||||||
settings: stuff.settings
|
settings: stuff.settings,
|
||||||
|
isRunning: stuff.isRunning
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
@@ -35,6 +36,7 @@
|
|||||||
export let database;
|
export let database;
|
||||||
export let settings;
|
export let settings;
|
||||||
export let privatePort;
|
export let privatePort;
|
||||||
|
export let isRunning;
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<div class="flex items-center space-x-2 p-6 text-2xl font-bold">
|
<div class="flex items-center space-x-2 p-6 text-2xl font-bold">
|
||||||
@@ -47,4 +49,4 @@
|
|||||||
<DatabaseLinks {database} />
|
<DatabaseLinks {database} />
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<Databases bind:database {privatePort} {settings} />
|
<Databases bind:database {privatePort} {settings} {isRunning} />
|
||||||
|
@@ -12,8 +12,8 @@
|
|||||||
import { onMount } from 'svelte';
|
import { onMount } from 'svelte';
|
||||||
const { id } = $page.params;
|
const { id } = $page.params;
|
||||||
let cannotDisable = settings.fqdn && destination.engine === '/var/run/docker.sock';
|
let cannotDisable = settings.fqdn && destination.engine === '/var/run/docker.sock';
|
||||||
// let scannedApps = [];
|
|
||||||
let loading = false;
|
let loading = false;
|
||||||
|
let loadingProxy = false;
|
||||||
let restarting = false;
|
let restarting = false;
|
||||||
async function handleSubmit() {
|
async function handleSubmit() {
|
||||||
loading = true;
|
loading = true;
|
||||||
@@ -25,12 +25,6 @@
|
|||||||
loading = false;
|
loading = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// async function scanApps() {
|
|
||||||
// scannedApps = [];
|
|
||||||
// const data = await fetch(`/destinations/${id}/scan.json`);
|
|
||||||
// const { containers } = await data.json();
|
|
||||||
// scannedApps = containers;
|
|
||||||
// }
|
|
||||||
onMount(async () => {
|
onMount(async () => {
|
||||||
if (state === false && destination.isCoolifyProxyUsed === true) {
|
if (state === false && destination.isCoolifyProxyUsed === true) {
|
||||||
destination.isCoolifyProxyUsed = !destination.isCoolifyProxyUsed;
|
destination.isCoolifyProxyUsed = !destination.isCoolifyProxyUsed;
|
||||||
@@ -71,6 +65,7 @@
|
|||||||
}
|
}
|
||||||
destination.isCoolifyProxyUsed = !destination.isCoolifyProxyUsed;
|
destination.isCoolifyProxyUsed = !destination.isCoolifyProxyUsed;
|
||||||
try {
|
try {
|
||||||
|
loadingProxy = true;
|
||||||
await post(`/destinations/${id}/settings.json`, {
|
await post(`/destinations/${id}/settings.json`, {
|
||||||
isCoolifyProxyUsed: destination.isCoolifyProxyUsed,
|
isCoolifyProxyUsed: destination.isCoolifyProxyUsed,
|
||||||
engine: destination.engine
|
engine: destination.engine
|
||||||
@@ -82,6 +77,8 @@
|
|||||||
}
|
}
|
||||||
} catch ({ error }) {
|
} catch ({ error }) {
|
||||||
return errorNotification(error);
|
return errorNotification(error);
|
||||||
|
} finally {
|
||||||
|
loadingProxy = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -187,6 +184,7 @@
|
|||||||
{#if $session.teamId === '0'}
|
{#if $session.teamId === '0'}
|
||||||
<div class="grid grid-cols-2 items-center">
|
<div class="grid grid-cols-2 items-center">
|
||||||
<Setting
|
<Setting
|
||||||
|
loading={loadingProxy}
|
||||||
disabled={cannotDisable}
|
disabled={cannotDisable}
|
||||||
bind:setting={destination.isCoolifyProxyUsed}
|
bind:setting={destination.isCoolifyProxyUsed}
|
||||||
on:click={changeProxySetting}
|
on:click={changeProxySetting}
|
||||||
|
Reference in New Issue
Block a user