DbCloudConfig.Client 1.0.1

There is a newer version of this package available.
See the version list below for details.
dotnet add package DbCloudConfig.Client --version 1.0.1
                    
NuGet\Install-Package DbCloudConfig.Client -Version 1.0.1
                    
This command is intended to be used within the Package Manager Console in Visual Studio, as it uses the NuGet module's version of Install-Package.
<PackageReference Include="DbCloudConfig.Client" Version="1.0.1" />
                    
For projects that support PackageReference, copy this XML node into the project file to reference the package.
<PackageVersion Include="DbCloudConfig.Client" Version="1.0.1" />
                    
Directory.Packages.props
<PackageReference Include="DbCloudConfig.Client" />
                    
Project file
For projects that support Central Package Management (CPM), copy this XML node into the solution Directory.Packages.props file to version the package.
paket add DbCloudConfig.Client --version 1.0.1
                    
#r "nuget: DbCloudConfig.Client, 1.0.1"
                    
#r directive can be used in F# Interactive and Polyglot Notebooks. Copy this into the interactive tool or source code of the script to reference the package.
#:package DbCloudConfig.Client@1.0.1
                    
#:package directive can be used in C# file-based apps starting in .NET 10 preview 4. Copy this into a .cs file before any lines of code to reference the package.
#addin nuget:?package=DbCloudConfig.Client&version=1.0.1
                    
Install as a Cake Addin
#tool nuget:?package=DbCloudConfig.Client&version=1.0.1
                    
Install as a Cake Tool

DB Cloud Config

DB Cloud Config adalah editor konfigurasi koneksi database berbasis .NET 10:

  • DbCloudConfig.Api: API Opx.Api.Web, default port 4545.
  • DbCloudConfig.Ui: Blazor Interactive Server, default HTTP development 4547.
  • DbCloudConfig.Client: wrapper Opx.Api.Client dengan IOpxApiClientFactory, HTTP/2, dan policy RequestVersionOrLower.
  • DbCloudConfig.Jwt: penerbit dan validator JWT HS256 bersama. Default session editor 15 menit (900 detik) dan batas maksimum 3600 detik.
  • DbCloudConfig.Contracts: kontrak API dan envelope AES-256-GCM.
  • DbCloudConfig.LinqToDb: shared loader cloud, decrypt delivery, mapper provider LinqToDB, dan helper setup AppDbContext.

Package NuGet DbCloudConfig.Client menggunakan versi 1.0.1, author opx, dan copyright Copyright © 2026 opx. Build Release tidak menghasilkan PDB. Untuk membuat package:

dotnet pack .\src\DbCloudConfig.Client\DbCloudConfig.Client.csproj -c Release -o .\artifacts\packages

Alternatif Command Prompt:

tools\Pack-DbCloudConfigClient.cmd

Seluruh response backend mengikuti envelope OPX: {"result":true|false,"data":...,"statusCode":"..."}. Payload sukses maupun detail error selalu berada di data, termasuk validasi model, exception controller, JWT 401/403, dan route yang tidak ditemukan. HTTP status asli tetap dipertahankan.

OPX AuthorizationGuard backend aktif secara default. Endpoint controller yang memerlukan autentikasi tetap dilindungi Bearer JWT, sedangkan endpoint status, setup/login, health, Swagger (Development), dan machine-token yang diberi [AllowAnonymous] tetap dapat diakses tanpa token.

Database OSF default berada di <content-root-api>/App_Data/cloud-config.osf. Lokasinya dapat diubah melalui CloudConfig:DbPath atau environment variable CloudConfig__DbPath. Setting aktif disimpan backend pada <content-root-api>/App_Data/cloud-config.settings.json. File settings hanya berisi path database aktif, token expiry, batas waktu delivery read-only, flag encrypt output, backend port, profil company, dan master DBOwner; password dan key tidak pernah disimpan di sana.

API tidak membuat database saat startup. Jika file tidak ditemukan, statusnya NotSetup dan UI menampilkan form setup untuk setup key, nama file .osf, dan password. Backend hanya menerima nama file aman dan membuat database pada folder DbPath; path absolut atau traversal tidak diterima. Jika file ditemukan, statusnya Ready dan UI meminta password database. Schema atau file baru diperiksa setelah password yang benar diberikan.

Model keamanan UI

Signing secret JWT tidak pernah dikirim ke browser dan tidak terdapat pada appsettings.json. UI berjalan sebagai Blazor Interactive Server dan wrapper DbCloudConfig.Client berjalan pada server UI dalam scope circuit pengguna. JWT hasil login dan key payload tetap berada di memori server UI; signing secret tetap hanya berada di environment API.

Saat setup atau login:

  1. Wrapper membuat key AES acak 32 byte.
  2. Wrapper mengirim password OSF dan public session input melalui HTTPS.
  3. API memvalidasi password lalu menerbitkan JWT menggunakan expiry aktif (default 15 menit/900 detik) melalui DbCloudConfig.Jwt.
  4. API mengikat JWT ke password dan key sesi dalam store memori terenkripsi.
  5. Response detail konfigurasi dienkripsi AES-256-GCM dengan key sesi; wrapper mendekripsinya pada server UI sebelum data dirender oleh komponen Blazor. Administrator dapat mematikan lapisan output ini; transport HTTPS tetap wajib untuk deployment.

Password form dikirim melalui circuit SignalR Blazor dan tidak disimpan ke localStorage atau sessionStorage. JWT dan key sesi hanya berada di memori scope circuit pada server UI. Saat circuit berakhir atau token kedaluwarsa, UI meminta login kembali. Deployment wajib memakai HTTPS pada UI dan API serta melindungi koneksi SignalR dari penyadapan.

DbCloudConfig.Jwt tetap menjadi source of truth penerbitan dan validasi token di backend. Wrapper sengaja memperlakukan token sebagai opaque backend-issued credential; memasukkan symmetric signing secret ke browser atau menerima “random token” tanpa signature akan membuat autentikasi dapat dipalsukan.

Konfigurasi dan menjalankan lokal

Buat dua nilai acak yang berbeda untuk JWT secret dan setup key:

$jwtBytes = New-Object byte[] 32
$setupBytes = New-Object byte[] 32
$rng = [Security.Cryptography.RandomNumberGenerator]::Create()
try {
    $rng.GetBytes($jwtBytes)
    $rng.GetBytes($setupBytes)
}
finally {
    $rng.Dispose()
}
$env:DB_CLOUD_CONFIG_JWT_SECRET_KEY = [Convert]::ToBase64String($jwtBytes)
$env:DB_CLOUD_CONFIG_SETUP_KEY = [Convert]::ToBase64String($setupBytes)

Setup key minimal 16 karakter dan hanya digunakan saat file database belum ada. Nama file dan password database dibuat oleh pengguna melalui form setup UI. Default nama file adalah cloud-config.osf.

Pada environment Development, UI menyediakan tombol Generate setup key. API hanya melayani generator tersebut dari koneksi loopback dan hanya selama database berstatus NotSetup. Key kriptografis yang baru langsung diisikan ke form dan disinkronkan ke environment proses API. Endpoint generator tidak tersedia pada production. Production tetap harus menerima setup key melalui DB_CLOUD_CONFIG_SETUP_KEY atau memakai autentikasi administrator eksternal sebelum generator production dapat diaktifkan dengan aman.

Jalankan API:

dotnet run --project .\src\DbCloudConfig.Api\DbCloudConfig.Api.csproj --no-launch-profile --urls http://localhost:4545

Jalankan UI Interactive Server pada terminal lain:

dotnet run --project .\src\DbCloudConfig.Ui\DbCloudConfig.Ui.csproj --launch-profile http

Buka http://localhost:4547 untuk development. Backend URL UI berada di src/DbCloudConfig.Ui/appsettings.json:

{
  "DbCloudConfigClient": {
    "HttpClientName": "db-cloud-config",
    "BaseAddress": "http://localhost:4545",
    "ClientId": "db-cloud-config-ui",
    "TimeoutSeconds": 30
  }
}

Konfigurasi repository memakai HTTP hanya untuk komunikasi loopback development antara UI Server dan API. Sebelum deployment, gunakan endpoint HTTPS production. Konfigurasi UI Server dapat dioverride dengan environment variable DbCloudConfigClient__BaseAddress. Environment variable berikut tetap dapat dipakai untuk konfigurasi API:

$env:CloudConfig__DbPath = "D:\DbCloudConfig\data\cloud-config.osf"
$env:CloudConfig__SettingsPath = "D:\DbCloudConfig\data\cloud-config.settings.json"

Identity yang menjalankan API membutuhkan permission read/write/modify pada folder DbPath. UI tidak memiliki akses ke file OSF. Karena panggilan wrapper berjalan server-to-server, browser tidak mengakses origin API secara langsung dan CORS tidak diperlukan untuk alur UI ini.

Jika circuit Interactive Server terputus, UI menampilkan progress bar reconnect tipis di bagian atas beserta nomor percobaan. Bar hilang otomatis setelah koneksi pulih. Jika reconnect gagal atau circuit ditolak, bar berubah menjadi status gagal dan menyediakan tautan Muat ulang.

Pada halaman editor, status sesi dan menu overflow tiga titik ditempatkan pada AppBar global. Aksi Settings dan Keluar berada di dalam menu tersebut. Tombol Tambah setting tetap berada pada header halaman tepat di atas grid; pada mobile tombol memenuhi lebar header agar mudah disentuh.

Wrapper

Registrasi wrapper:

services.AddDbCloudConfigClient(configuration);

Alur penggunaan:

var status = await client.GetStatusAsync(cancellationToken);

if (status.RequiresSetup)
    await client.SetupAsync(setupKey, databasePassword, cancellationToken);
else
    await client.LoginAsync(databasePassword, cancellationToken);

var rows = await client.ListAsync(cancellationToken: cancellationToken);
var detail = await client.GetAsync(
    "RELEASE",
    "PRIMARY",
    cancellationToken);

Wrapper tidak membuat HttpClient langsung. Named client dibuat oleh Opx.Api.Client, default request memakai HTTP/2 dan dapat turun ke versi lebih rendah bila server/proxy tidak mendukung HTTP/2. Pada Interactive Server, request dijalankan oleh HttpClient server UI melalui factory yang sama.

Menu Settings hanya tersedia setelah login dan menyediakan:

  • Language / Bahasa: pilihan English (EN) dan Indonesia (ID). Default backend dan UI adalah EN. Pilihan disimpan pada settings backend dan ikut dikirim melalui endpoint status agar halaman setup/login memakai bahasa aktif sebelum autentikasi.
  • Token expired: 30 sampai 3600 detik. Perubahan berlaku pada login berikutnya.
  • Expired date: label informasi read-only. Backend menetapkan default lima tahun sejak database dibuat atau diaktifkan. Nilai ini tidak dapat diubah melalui UI atau update Settings biasa. Setelah waktu terlewati, endpoint detail mengembalikan HTTP 410.
  • Backend URL: origin HTTP/HTTPS absolut tanpa path, misalnya https://localhost:4545. URL digunakan oleh self-hosted Kestrel setelah API direstart. Argumen --urls atau environment ASPNETCORE_URLS tetap menjadi explicit override. Setelah URL berubah, sesuaikan DbCloudConfigClient:BaseAddress pada UI Server lalu restart UI.
  • Encrypt output: jika aktif, detail response dibungkus AES-256-GCM. Jika tidak aktif, payload detail dikirim plaintext di dalam HTTPS dan response OPX. Enkripsi file OSF di backend tetap aktif pada kedua mode.
  • Ubah password: API membuat database sementara dengan password baru, menyalin seluruh schema dan row legacy, memvalidasinya, lalu melakukan atomic replace. Database dengan password lama dipertahankan sebagai file *.password-backup.bak; seluruh session kemudian dihapus.
  • New database: membuat file .osf baru pada folder backend yang sama dan menjadikannya database aktif. Database lama tidak dihapus. Nama file tidak boleh mengandung path atau traversal.

Setelah mengganti password atau membuat database, pengguna wajib login kembali. Perubahan backend port memerlukan restart API. Bila UI terhubung langsung ke Kestrel tanpa reverse proxy, sesuaikan juga DbCloudConfigClient:BaseAddress pada appsettings.json, lalu restart UI. Binding IIS/reverse proxy tetap dikendalikan oleh konfigurasi hosting.

Menu Setup pada AppBar menyimpan profil aplikasi berupa Company Name, Description, dan master data DBOwner ke file settings backend. DBOwner bersifat unik tanpa membedakan huruf besar/kecil dan menjadi sumber pilihan field Owner pada dialog setting database. Owner tetap nullable. Record lama dengan owner yang belum ada di master tetap dapat dipilih sebagai nilai legacy dan tidak dihapus otomatis.

Endpoint

GET    /health
GET    /api/v1/session/status
POST   /api/v1/session/setup
POST   /api/v1/session/login
POST   /api/v1/session/development/setup-key  (Development + loopback only)
GET    /api/v1/database-configs?environment=RELEASE
GET    /api/v1/database-configs/{environment}/{name}
PUT    /api/v1/database-configs/{environment}/{name}
POST   /api/v1/database-configs/{environment}/{name}/duplicate
DELETE /api/v1/database-configs/{environment}/{name}
GET    /api/v1/settings
PUT    /api/v1/settings
GET    /api/v1/settings/setup
PUT    /api/v1/settings/setup
POST   /api/v1/settings/change-password
POST   /api/v1/settings/databases

Endpoint status, setup, dan login bersifat anonymous. Setup tetap dilindungi DB_CLOUD_CONFIG_SETUP_KEY, hanya tersedia ketika database belum ada, dan melewati rate limiting Opx.Api.Web. Endpoint CRUD memerlukan Bearer JWT serta sesi server yang belum kedaluwarsa.

Body endpoint PUT:

{
  "provider": "Microsoft.Data.SqlClient",
  "connectionString": "Server=...;Database=...;Encrypt=True",
  "commandTimeoutSeconds": 30,
  "owner": null,
  "isActive": true,
  "metadata": {
    "region": "primary"
  }
}

owner adalah parameter opsional dengan panjang maksimal 100 karakter. Nilai kosong dinormalisasi menjadi null. Record lama yang menyimpan owner pada metadata.owner tetap dibaca sebagai fallback kompatibilitas.

isActive menentukan status aktif konfigurasi dan default-nya true. Editor menyediakan checkbox Konfigurasi aktif. Record OSF lama yang belum memiliki field ini otomatis dianggap aktif; menonaktifkan konfigurasi tidak menghapus record atau connection string.

Editor UI menyediakan pilihan provider berikut:

  • MySQL disimpan sebagai MySql.8.0.MySqlConnector.
  • MariaDB disimpan sebagai MariaDB.10.MySqlConnector.
  • SQL Server disimpan sebagai Microsoft.Data.SqlClient.
  • PostgreSQL disimpan sebagai Npgsql.
  • SAP HANA disimpan sebagai SapHana.Odbc.

Record lama dengan provider MySqlConnector tetap dapat ditampilkan, diedit, dan dites sebagai MySQL tanpa diubah otomatis.

Environment pada editor menyediakan tiga mode pengguna:

  • RELEASE disimpan sebagai RELEASE untuk record baru.
  • STAGING disimpan sebagai STAGING.
  • DEBUG disimpan sebagai DEBUG.

Konfigurasi baru memakai RELEASE sebagai default. Record lama yang sudah tersimpan sebagai PRODUCTION tetap ditampilkan sebagai RELEASE dan dapat diedit tanpa diubah otomatis. Nilai environment legacy lain tetap dapat ditampilkan saat membuka data lama.

Pada viewport mobile (maksimal 760 px), daftar setting berubah dari tabel menjadi card. Setiap card menampilkan environment, nama, provider, waktu perubahan, serta ikon Edit/Duplicate/View endpoint/Hapus dalam satu baris pada header. Setiap ikon memiliki label aksesibel dan tooltip. Desktop tetap memakai tabel dengan aksi berbentuk teks.

Layout halaman utama memakai seluruh lebar viewport karena aplikasi tidak memiliki sidebar atau menu hamburger. Batas lebar tetap diterapkan pada kartu login/setup dan modal agar form tetap nyaman dibaca.

Seluruh UI mengikuti resolusi viewport secara responsif. Desktop menggunakan grid penuh, sedangkan layar sempit menggunakan card dan kontrol bertumpuk untuk mencegah overflow halaman. Modal dibatasi oleh lebar/tinggi viewport, memiliki scroll internal untuk konten panjang, dan menjaga aksi utama tetap dapat dijangkau pada desktop, tablet, maupun mobile.

Tombol View endpoint pada setiap setting membuka modal berisi URL absolut GET /api/v1/database-configs/{environment}/{name} dan tombol Copy endpoint. URL mengikuti BaseAddress wrapper pada konfigurasi UI. Modal hanya menampilkan alamat endpoint, bukan JWT atau secret; consumer tetap wajib mengirim Bearer JWT yang valid saat memanggil endpoint.

Tombol Execute GET pada modal menjalankan request melalui wrapper dan sesi JWT editor yang aktif, lalu menampilkan response delivery mentah sebagai JSON terformat. Jika backend mengaktifkan encrypted output, yang ditampilkan adalah encrypted envelope; jika dinonaktifkan, yang ditampilkan adalah plain payload. Token autentikasi tidak disertakan dalam output. Plain payload dapat memuat connection string atau credential sensitif dan hanya boleh digunakan pada sesi editor yang dipercaya.

Identitas unik setting adalah kombinasi Environment + Nama. Nama yang sama boleh digunakan pada RELEASE, STAGING, dan DEBUG sebagai record berbeda. Menyimpan kembali pasangan Environment/Nama yang sama akan memperbarui record tersebut, bukan membuat duplikat baru.

Tombol Duplicate menyalin seluruh value setting—provider, connection string, timeout, metadata, owner, dan status aktif—kecuali Environment dan Name target. Dialog menyediakan pilihan RELEASE, STAGING, atau DEBUG serta meminta Name baru. UI memeriksa pasangan Environment/Name target terlebih dahulu, kemudian backend mengulang pemeriksaan secara atomik. Jika target sudah ada, API mengembalikan HTTP 409 dan tidak mengubah record sumber maupun target.

Tombol Setup connection di samping provider membuka generator connection string untuk SQL Server, MySQL, MariaDB, PostgreSQL, dan SAP HANA. Tool menyediakan host, port default, database, username, password, TLS/encryption, dan opsi trust server certificate. Nilai dibangun memakai DbConnectionStringBuilder agar karakter khusus ter-escape dengan benar, lalu hanya mengisi editor; data baru dikirim ke API ketika pengguna menekan Simpan.

Untuk SQL Server, tool menyediakan Windows Authentication (Trusted Connection). Pada mode ini username/password dinonaktifkan dan generator menghasilkan Integrated Security=True. Tombol tes koneksi menggunakan identity proses UI Server, sehingga akun dotnet, IIS App Pool, atau service account yang menjalankan UI harus memiliki login dan permission pada SQL Server.

Jika editor sudah memiliki connection string, Setup connection mem-parsing nilai existing dan mengisi seluruh field tool tanpa perlu mengetik ulang. Nilai credential tetap berada pada circuit server UI dan tidak ditulis ke log. Untuk SQL Server named instance tanpa port eksplisit, tool mempertahankan format server\instance dan membiarkan SQL Browser menemukan dynamic port. Checkbox Gunakan port eksplisit tersedia saat koneksi memang harus memakai server\instance,port.

Tombol Tes koneksi membuka koneksi langsung dari server UI memakai driver Microsoft.Data.SqlClient, MySqlConnector, Npgsql, atau System.Data.Odbc sesuai engine. Percobaan dibatasi 10 detik, mematikan pooling pada provider yang mendukung keyword tersebut, tidak menyimpan hasil tes, dan menampilkan status serta durasi. Kegagalan tes tidak mengubah connection string editor dan tidak mengirim konfigurasi ke Cloud Config API.

SAP HANA memakai System.Data.Odbc dan connection string Driver={HDBODBC};ServerNode=host:port;DatabaseName=.... Mesin server UI wajib memiliki SAP HANA Client 64-bit agar driver HDBODBC tersedia. Port default generator adalah 30015; TLS aktif secara default dan validasi sertifikat hanya dinonaktifkan jika opsi trust server certificate dipilih. Tombol ini tersedia baik di connection string generator maupun langsung di dialog tambah/edit setting, sehingga connection string manual atau existing dapat diuji sebelum disimpan.

Table OSF CLOUD_CONFIG memakai kolom SECTION, KEYNAME, DATA, CONTENT_TYPE, dan IS_SECRET. Route {environment}/{name} dipetakan ke SECTION/KEYNAME, yang menjadi primary key komposit. Connection string berada dalam file OSF terenkripsi dan response detail memiliki lapisan enkripsi AES-256-GCM tambahan. Lapisan response tersebut mengikuti setting EncryptOutput; enkripsi at-rest OSF tidak terpengaruh.

Sample Chinook

Sample adaptasi Chinook yang memuat konfigurasi database DEBUG/CHINOOK dari Cloud Config tersedia di samples/chinook-cloud-config. Sample menggunakan assertion JWT yang ditandatangani private certificate, menukarkannya dengan JWT read-only dua menit, mengambil payload melalui DbCloudConfig.Client, mendekripsinya, lalu memasok provider dan connection string ke DbContext. Password OSF hanya tersedia sebagai file DPAPI terenkripsi pada backend dan tidak diberikan kepada Chinook. Proses load yang aman dapat dilihat dari operasi Swagger GET /api/cloud-config/status; endpoint itu hanya menampilkan state, endpoint sumber, provider, waktu load, dan tahapan non-sensitif. Detail provisioning dan menjalankan sample tersedia pada README di folder sample.

Machine Access berdasarkan Owner

Menu Machine Access pada AppBar editor mengelola autentikasi backend yang mengambil konfigurasi database. Administrator memilih Client ID dari dropdown client yang sudah terdaftar atau memilih New client ID..., lalu memilih DBOwner dan Database Name. Policy tersebut berlaku untuk seluruh environment (RELEASE, STAGING, dan DEBUG) pada database yang dipilih, lalu mengisi password PFX. Editor menghasilkan PFX sebagai download satu kali. Backend hanya menyimpan public CER, kid fingerprint SHA-256, policy, status, dan masa berlaku.

Contoh hris-release dengan Owner HRIS dan Environment RELEASE dapat mengambil seluruh record RELEASE yang memiliki Owner HRIS, misalnya FINAC dan FINGERSPOT. Certificate tersebut tidak dapat mengambil DEBUG atau record milik Owner lain. Gunakan certificate berbeda untuk DEBUG dan RELEASE.

Tool menyediakan rotasi certificate, revoke, dan aktivasi kembali. Rotasi menghasilkan PFX baru dan langsung membatalkan public key lama. PFX/password, private key, assertion, JWT, password OSF, serta connection string tidak pernah disimpan dalam registry machine client. Production wajib memakai HTTPS dan PFX hasil download harus dipindahkan ke certificate store atau secret store milik backend tujuan.

Build

Repository hanya memakai feed publik NuGet.org dari NuGet.Config; tidak ada NuGet lokal.

dotnet restore .\DbCloudConfig.slnx --configfile .\NuGet.Config
dotnet build .\DbCloudConfig.slnx --no-restore -c Release
Product Compatible and additional computed target framework versions.
.NET net10.0 is compatible.  net10.0-android was computed.  net10.0-browser was computed.  net10.0-ios was computed.  net10.0-maccatalyst was computed.  net10.0-macos was computed.  net10.0-tvos was computed.  net10.0-windows was computed. 
Compatible target framework(s)
Included target framework(s) (in package)
Learn more about Target Frameworks and .NET Standard.

NuGet packages (3)

Showing the top 3 NuGet packages that depend on DbCloudConfig.Client:

Package Downloads
DbCloudConfig.Configuration

Loads encrypted DB Cloud Config records into Microsoft.Extensions.Configuration.

DbCloudConfig.AspNetCore

ASP.NET Core dependency injection and health checks for DB Cloud Config.

DbCloudConfig.LinqToDb

Shared cloud configuration loader and LinqToDB provider setup helper.

GitHub repositories

This package is not used by any popular GitHub repositories.

Version Downloads Last Updated
1.0.15 149 8/25/2026
1.0.14 137 8/12/2026
1.0.13 140 8/2/2026
1.0.11 141 7/29/2026
1.0.10 141 7/28/2026
1.0.9 140 7/28/2026
1.0.7 128 7/28/2026
1.0.6 142 7/28/2026
1.0.5 133 7/27/2026
1.0.1 155 7/24/2026