security: Add proper authentication, RBAC, and tenant isolation
- Add password hashing with bcrypt - Add AuthService with proper login - Add password strength validation - Add RBAC middleware (AdminOnly, ManagerOrAdmin) - Add tenant isolation middleware - Update CRM handler with tenant filtering - Add JWT fallback for development mode - Add user context helpers - Build successful
This commit is contained in:
@@ -0,0 +1,82 @@
|
||||
package handlers
|
||||
|
||||
import (
|
||||
"net/http"
|
||||
"time"
|
||||
)
|
||||
|
||||
// FortnoxHandler hanterar Fortnox-integration
|
||||
type FortnoxHandler struct{}
|
||||
|
||||
func NewFortnoxHandler() *FortnoxHandler {
|
||||
return &FortnoxHandler{}
|
||||
}
|
||||
|
||||
// FortnoxVoucher representerar ett Fortnox-verifikat
|
||||
type FortnoxVoucher struct {
|
||||
ID string `json:"id"`
|
||||
Date string `json:"date"`
|
||||
Text string `json:"text"`
|
||||
Rows []FortnoxRow `json:"rows"`
|
||||
Synced bool `json:"synced"`
|
||||
SyncedAt *time.Time `json:"synced_at,omitempty"`
|
||||
}
|
||||
|
||||
// FortnoxRow representerar en Fortnox-rad
|
||||
type FortnoxRow struct {
|
||||
Account string `json:"account"`
|
||||
AccountName string `json:"account_name"`
|
||||
Debit float64 `json:"debit"`
|
||||
Credit float64 `json:"credit"`
|
||||
Description string `json:"description"`
|
||||
}
|
||||
|
||||
// GetStatus returnerar Fortnox-kopplingsstatus
|
||||
func (h *FortnoxHandler) GetStatus(w http.ResponseWriter, r *http.Request) {
|
||||
status := map[string]interface{}{
|
||||
"configured": false,
|
||||
"client_id": "",
|
||||
"auth_url": "https://apps.fortnox.se/oauth-v1/auth",
|
||||
"token_url": "https://apps.fortnox.se/oauth-v1/token",
|
||||
"api_base": "https://api.fortnox.se/3",
|
||||
"setup_required": true,
|
||||
}
|
||||
|
||||
writeJSON(w, http.StatusOK, map[string]interface{}{
|
||||
"ok": true,
|
||||
"fortnox": status,
|
||||
})
|
||||
}
|
||||
|
||||
// GetVouchers returnerar Fortnox-verifikat
|
||||
func (h *FortnoxHandler) GetVouchers(w http.ResponseWriter, r *http.Request) {
|
||||
vouchers := []FortnoxVoucher{
|
||||
{
|
||||
ID: "fnx-001",
|
||||
Date: "2026-08-01",
|
||||
Text: "Faktura #1001",
|
||||
Rows: []FortnoxRow{
|
||||
{Account: "1510", AccountName: "Kundfordringar", Debit: 25000, Credit: 0, Description: "Faktura #1001"},
|
||||
{Account: "3010", AccountName: "Försäljning", Debit: 0, Credit: 25000, Description: "Faktura #1001"},
|
||||
},
|
||||
Synced: true,
|
||||
SyncedAt: timePtr(time.Now().Add(-48 * time.Hour)),
|
||||
},
|
||||
{
|
||||
ID: "fnx-002",
|
||||
Date: "2026-08-02",
|
||||
Text: "Leverantörsfaktura AWS",
|
||||
Rows: []FortnoxRow{
|
||||
{Account: "6540", AccountName: "IT-kostnader", Debit: 8500, Credit: 0, Description: "AWS hosting"},
|
||||
{Account: "2440", AccountName: "Leverantörsskulder", Debit: 0, Credit: 8500, Description: "AWS hosting"},
|
||||
},
|
||||
Synced: true,
|
||||
SyncedAt: timePtr(time.Now().Add(-24 * time.Hour)),
|
||||
},
|
||||
}
|
||||
|
||||
writeJSON(w, http.StatusOK, map[string]interface{}{
|
||||
"ok": true,
|
||||
"vouchers": vouchers,
|
||||
})
|
||||
}
|
||||
Reference in New Issue
Block a user