diff --git a/api/setup_manager.py b/api/setup_manager.py index a9a01c0..6e420b5 100644 --- a/api/setup_manager.py +++ b/api/setup_manager.py @@ -247,6 +247,7 @@ class SetupManager: self.config_manager.set_ddns_config(ddns_cfg) # ── trigger DDNS registration for pic_ngo ───────────────────────── + warnings: List[str] = [] if domain_mode == 'pic_ngo': try: from ddns_manager import DDNSManager @@ -254,13 +255,29 @@ class SetupManager: ddns_mgr.register(cell_name, '') logger.info(f'DDNS registered: {cell_name}.pic.ngo') except Exception as exc: - logger.warning(f'DDNS registration failed (will retry at next heartbeat): {exc}') + msg = str(exc) + logger.warning(f'DDNS registration failed: {msg}') + if '409' in msg or 'taken' in msg.lower(): + warnings.append( + f'The name "{cell_name}" is already registered on pic.ngo. ' + 'HTTPS will not be active until you re-register: go to ' + 'Settings → DDNS and click Re-register, or choose a different name.' + ) + else: + warnings.append( + 'DDNS registration could not be completed right now ' + f'({msg}). The cell will retry automatically. ' + 'HTTPS will activate once registration succeeds.' + ) # ── mark setup complete (must be last) ───────────────────────── self.config_manager.set_identity_field('setup_complete', True) logger.info(f"Setup completed. cell_name={cell_name!r}, domain_mode={domain_mode!r}") - return {'success': True, 'redirect': '/login'} + result: Dict[str, Any] = {'success': True, 'redirect': '/login'} + if warnings: + result['warnings'] = warnings + return result finally: try: diff --git a/webui/src/pages/Setup.jsx b/webui/src/pages/Setup.jsx index 2968b2e..f7734db 100644 --- a/webui/src/pages/Setup.jsx +++ b/webui/src/pages/Setup.jsx @@ -540,8 +540,9 @@ function Step4Review({ domainType, domainName, timezone, onBack, onSubmit, submi export default function Setup() { const navigate = useNavigate(); - const [step, setStep] = useState(1); - const [done, setDone] = useState(false); + const [step, setStep] = useState(1); + const [done, setDone] = useState(false); + const [setupWarnings, setSetupWarnings] = useState([]); const [password, setPassword] = useState(''); const [passwordConfirm, setPasswordConfirm] = useState(''); @@ -600,9 +601,13 @@ export default function Setup() { }; try { - await setupAPI.complete(payload); + const res = await setupAPI.complete(payload); + const warnings = res?.data?.warnings || []; + setSetupWarnings(warnings); setDone(true); - setTimeout(() => navigate('/login', { replace: true }), 2000); + if (warnings.length === 0) { + setTimeout(() => navigate('/login', { replace: true }), 2000); + } } catch (e) { setSubmitError( e?.response?.data?.errors?.join(' ') || @@ -617,10 +622,27 @@ export default function Setup() { if (done) { return (
-
+

Setup complete!

-

Redirecting to login...

+ {setupWarnings.length > 0 ? ( +
+ {setupWarnings.map((w, i) => ( +
+ +

{w}

+
+ ))} + +
+ ) : ( +

Redirecting to login...

+ )}
);