diff --git a/static/js/index.js b/static/js/index.js index 3ecdabe..407907a 100644 --- a/static/js/index.js +++ b/static/js/index.js @@ -13,6 +13,8 @@ window.app = Vue.createApp({ currencies: [], settings: null, isAdmin: false, + isSuperUser: false, + castleWalletConfigured: false, expenseDialog: { show: false, description: '', @@ -104,16 +106,21 @@ window.app = Vue.createApp({ }, async loadSettings() { try { + // Try with admin key first to check settings const response = await LNbits.api.request( 'GET', '/castle/api/v1/settings', - this.g.user.wallets[0].adminkey + this.g.user.wallets[0].inkey ) this.settings = response.data - this.isAdmin = true + this.castleWalletConfigured = !!(this.settings && this.settings.castle_wallet_id) + + // Check if user is super user by seeing if they can access admin features + this.isSuperUser = this.g.user.super_user || false + this.isAdmin = this.g.user.admin || this.isSuperUser } catch (error) { - // Not admin or settings not available - this.isAdmin = false + // Settings not available + this.castleWalletConfigured = false } }, showSettingsDialog() { @@ -121,6 +128,14 @@ window.app = Vue.createApp({ this.settingsDialog.show = true }, async submitSettings() { + if (!this.settingsDialog.castleWalletId) { + this.$q.notify({ + type: 'warning', + message: 'Castle Wallet ID is required' + }) + return + } + this.settingsDialog.loading = true try { await LNbits.api.request( diff --git a/templates/castle/index.html b/templates/castle/index.html index 4878b80..07c0340 100644 --- a/templates/castle/index.html +++ b/templates/castle/index.html @@ -16,15 +16,37 @@
🏰 Castle Accounting

Track expenses, receivables, and balances for the collective

-
+
- Settings + Settings (Super User Only)
+ + + +
+ Setup Required: Castle Wallet ID must be configured before the extension can function. +
+ +
+ + + +
+ Setup Required: This extension requires configuration by the super user before it can be used. +
+
+ @@ -66,8 +88,15 @@
Quick Actions
- + Add Expense + + Castle wallet must be configured first + View Transactions @@ -248,12 +277,22 @@
Castle Settings
+ + +
+ Super User Only: Only the super user can modify these settings. +
+
+
@@ -261,10 +300,18 @@
- + Save Settings - Cancel + + {% raw %}{{ isSuperUser ? 'Cancel' : 'Close' }}{% endraw %} +
diff --git a/views_api.py b/views_api.py index 7db76d9..d2bc6f4 100644 --- a/views_api.py +++ b/views_api.py @@ -1,8 +1,13 @@ from http import HTTPStatus from fastapi import APIRouter, Depends, HTTPException -from lnbits.core.models import WalletTypeInfo -from lnbits.decorators import require_admin_key, require_invoice_key +from lnbits.core.models import User, WalletTypeInfo +from lnbits.decorators import ( + check_super_user, + check_user_exists, + require_admin_key, + require_invoice_key, +) from lnbits.utils.exchange_rates import allowed_currencies, fiat_amount_as_satoshis from .crud import ( @@ -37,6 +42,20 @@ from .services import get_settings, update_settings castle_api_router = APIRouter() +# ===== HELPER FUNCTIONS ===== + + +async def check_castle_wallet_configured() -> str: + """Ensure castle wallet is configured, return wallet_id""" + settings = await get_settings("admin") + if not settings or not settings.castle_wallet_id: + raise HTTPException( + status_code=HTTPStatus.BAD_REQUEST, + detail="Castle wallet not configured. Please contact the super user to configure the Castle wallet in settings.", + ) + return settings.castle_wallet_id + + # ===== UTILITY ENDPOINTS ===== @@ -459,18 +478,27 @@ async def api_pay_user( @castle_api_router.get("/api/v1/settings") async def api_get_settings( - wallet: WalletTypeInfo = Depends(require_admin_key), + user: User = Depends(check_user_exists), ) -> CastleSettings: - """Get Castle settings (admin only)""" + """Get Castle settings""" user_id = "admin" - return await get_settings(user_id) + settings = await get_settings(user_id) + # Return empty settings if not configured (so UI can show setup screen) + if not settings: + return CastleSettings() + return settings @castle_api_router.put("/api/v1/settings") async def api_update_settings( data: CastleSettings, - wallet: WalletTypeInfo = Depends(require_admin_key), + user: User = Depends(check_super_user), ) -> CastleSettings: - """Update Castle settings (admin only)""" + """Update Castle settings (super user only)""" + if not data.castle_wallet_id: + raise HTTPException( + status_code=HTTPStatus.BAD_REQUEST, + detail="Castle wallet ID is required", + ) user_id = "admin" return await update_settings(user_id, data)