diff --git a/compose/stack.yaml b/compose/stack.yaml index 5894f81..7da1130 100644 --- a/compose/stack.yaml +++ b/compose/stack.yaml @@ -54,7 +54,7 @@ services: command: - sh - -c - - "apk add --no-cache curl sqlite3 >/dev/null 2>&1 && exec /opt/nextworkspace/nextworkspace" + - "apk add --no-cache curl sqlite >/dev/null 2>&1 && exec /opt/nextworkspace/nextworkspace" environment: - CONFIG_DIR=/opt/nextworkspace/config/nextworkspace - AUTHELIA_SECRET={AUTHELIA_SECRET} diff --git a/main.go b/main.go index f03872a..9d94b16 100644 --- a/main.go +++ b/main.go @@ -893,25 +893,46 @@ func enforceTOTP(w http.ResponseWriter, r *http.Request) { return } - // Update Authelia's user_preferences to require TOTP on next login - dbPath := "/opt/nextworkspace/data/authelia/db.sqlite" - cmd := exec.Command("sqlite3", dbPath, - "INSERT OR REPLACE INTO user_preferences (id, username, method) VALUES ((SELECT id FROM user_preferences WHERE username='"+user+"'), '"+user+"', 'totp')") - err := cmd.Run() + // Try the new authelia-api policy endpoint first (if deployed) + token := os.Getenv("AUTHELIA_SECRET") + policyBody, _ := json.Marshal(map[string]interface{}{ + "name": "TOTP enforcement for " + user, + "domain": []string{"*"}, + "subjects": []string{"user:" + user}, + "policy": "two_factor", + }) + apiReq, _ := http.NewRequest("POST", "http://authelia:8080/api/policies", bytes.NewReader(policyBody)) + apiReq.Header.Set("Authorization", "Bearer "+token) + apiReq.Header.Set("Content-Type", "application/json") - if err != nil { - json.NewEncoder(w).Encode(map[string]interface{}{ - "status": "error", - "error": "Failed to update preferences", - "totp_required": true, - }) - return + apiResp, apiErr := http.DefaultClient.Do(apiReq) + apiOk := apiErr == nil && apiResp != nil && apiResp.StatusCode == 201 + + if apiOk { + apiResp.Body.Close() } - json.NewEncoder(w).Encode(map[string]interface{}{ - "status": "enforced", - "totp_required": true, - }) + // Set user_preference regardless (triggers Authelia's enrollment prompt on next login) + exec.Command("sqlite3", "/opt/nextworkspace/data/authelia/db.sqlite", + "INSERT OR REPLACE INTO user_preferences (username, method) VALUES ('"+user+"', 'totp')").Run() + + if apiOk { + json.NewEncoder(w).Encode(map[string]interface{}{ + "status": "enforced", + "totp_required": true, + "policy_created": true, + }) + } else { + json.NewEncoder(w).Encode(map[string]interface{}{ + "status": "enforced", + "totp_required": true, + "policy_created": false, + }) + } + if apiResp != nil { + apiResp.Body.Close() + } + return } // --- Translation system ---