You've already forked openaccounting-server
forked from cybercinch/openaccounting-server
- Add JWT-based secure file access for local storage with 1-hour expiry - Implement GORM repository methods for attachment CRUD operations - Add secure file serving endpoint with token validation - Update storage interface to support user context in URL generation - Add comprehensive security features including path traversal protection - Update documentation with security model and configuration examples - Add utility functions for hex/byte conversion and UUID validation - Configure secure file permissions (0600) for uploaded files 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude <noreply@anthropic.com>
68 lines
4.3 KiB
Go
68 lines
4.3 KiB
Go
package api
|
|
|
|
import (
|
|
"github.com/ant0ine/go-json-rest/rest"
|
|
"github.com/openaccounting/oa-server/core/ws"
|
|
)
|
|
|
|
func GetRouter(auth *AuthMiddleware, prefix string) (rest.App, error) {
|
|
return rest.MakeRouter(
|
|
rest.Get(prefix+"/user", auth.RequireAuth(GetUser)),
|
|
rest.Put(prefix+"/user", PutUser),
|
|
rest.Post(prefix+"/user/verify", VerifyUser),
|
|
rest.Post(prefix+"/user/reset-password", ResetPassword),
|
|
rest.Post(prefix+"/users", PostUser),
|
|
rest.Post(prefix+"/orgs", auth.RequireAuth(PostOrg)),
|
|
rest.Get(prefix+"/orgs", auth.RequireAuth(GetOrgs)),
|
|
rest.Get(prefix+"/orgs/:orgId", auth.RequireAuth(GetOrg)),
|
|
rest.Put(prefix+"/orgs/:orgId", auth.RequireAuth(PutOrg)),
|
|
rest.Get(prefix+"/orgs/:orgId/ledgers", auth.RequireAuth(GetOrgAccounts)),
|
|
rest.Post(prefix+"/orgs/:orgId/ledgers", auth.RequireAuth(PostAccount)),
|
|
rest.Put(prefix+"/orgs/:orgId/ledgers/:accountId", auth.RequireAuth(PutAccount)),
|
|
rest.Delete(prefix+"/orgs/:orgId/ledgers/:accountId", auth.RequireAuth(DeleteAccount)),
|
|
rest.Get(prefix+"/orgs/:orgId/ledgers/:accountId/transactions", auth.RequireAuth(GetTransactionsByAccount)),
|
|
rest.Get(prefix+"/orgs/:orgId/accounts", auth.RequireAuth(GetOrgAccounts)),
|
|
rest.Get(prefix+"/orgs/:orgId/accounts/:accountId", auth.RequireAuth(GetOrgAccount)),
|
|
rest.Post(prefix+"/orgs/:orgId/accounts", auth.RequireAuth(PostAccount)),
|
|
rest.Put(prefix+"/orgs/:orgId/accounts/:accountId", auth.RequireAuth(PutAccount)),
|
|
rest.Delete(prefix+"/orgs/:orgId/accounts/:accountId", auth.RequireAuth(DeleteAccount)),
|
|
rest.Get(prefix+"/orgs/:orgId/accounts/:accountId/transactions", auth.RequireAuth(GetTransactionsByAccount)),
|
|
rest.Get(prefix+"/orgs/:orgId/transactions", auth.RequireAuth(GetTransactionsByOrg)),
|
|
rest.Post(prefix+"/orgs/:orgId/transactions", auth.RequireAuth(PostTransaction)),
|
|
rest.Put(prefix+"/orgs/:orgId/transactions/:transactionId", auth.RequireAuth(PutTransaction)),
|
|
rest.Delete(prefix+"/orgs/:orgId/transactions/:transactionId", auth.RequireAuth(DeleteTransaction)),
|
|
rest.Get(prefix+"/orgs/:orgId/transactions/:transactionId/attachments", auth.RequireAuth(GetAttachments)),
|
|
rest.Post(prefix+"/orgs/:orgId/transactions/:transactionId/attachments", auth.RequireAuth(PostAttachment)),
|
|
rest.Get(prefix+"/orgs/:orgId/transactions/:transactionId/attachments/:attachmentId", auth.RequireAuth(GetAttachment)),
|
|
rest.Get(prefix+"/orgs/:orgId/transactions/:transactionId/attachments/:attachmentId/download", auth.RequireAuth(DownloadAttachment)),
|
|
rest.Delete(prefix+"/orgs/:orgId/transactions/:transactionId/attachments/:attachmentId", auth.RequireAuth(DeleteAttachment)),
|
|
|
|
// New storage-based attachment endpoints
|
|
rest.Post(prefix+"/attachments", auth.RequireAuth(PostAttachmentWithStorage)),
|
|
rest.Get(prefix+"/attachments/:id", auth.RequireAuth(GetAttachmentWithStorage)),
|
|
rest.Get(prefix+"/attachments/:id/url", auth.RequireAuth(GetAttachmentDownloadURL)),
|
|
rest.Delete(prefix+"/attachments/:id", auth.RequireAuth(DeleteAttachmentWithStorage)),
|
|
|
|
// Secure file serving endpoint (no auth required - token validates access)
|
|
rest.Get("/secure-files", GetSecureFile),
|
|
rest.Get(prefix+"/orgs/:orgId/prices", auth.RequireAuth(GetPrices)),
|
|
rest.Post(prefix+"/orgs/:orgId/prices", auth.RequireAuth(PostPrice)),
|
|
rest.Delete(prefix+"/orgs/:orgId/prices/:priceId", auth.RequireAuth(DeletePrice)),
|
|
rest.Get("/ws", ws.Handler),
|
|
rest.Post(prefix+"/sessions", auth.RequireAuth(PostSession)),
|
|
rest.Delete(prefix+"/sessions/:sessionId", auth.RequireAuth(DeleteSession)),
|
|
rest.Get(prefix+"/apikeys", auth.RequireAuth(GetApiKeys)),
|
|
rest.Post(prefix+"/apikeys", auth.RequireAuth(PostApiKey)),
|
|
rest.Put(prefix+"/apikeys/:apiKeyId", auth.RequireAuth(PutApiKey)),
|
|
rest.Delete(prefix+"/apikeys/:apiKeyId", auth.RequireAuth(DeleteApiKey)),
|
|
rest.Get(prefix+"/orgs/:orgId/invites", auth.RequireAuth(GetInvites)),
|
|
rest.Post(prefix+"/orgs/:orgId/invites", auth.RequireAuth(PostInvite)),
|
|
rest.Put(prefix+"/orgs/:orgId/invites/:inviteId", auth.RequireAuth(PutInvite)),
|
|
rest.Delete(prefix+"/orgs/:orgId/invites/:inviteId", auth.RequireAuth(DeleteInvite)),
|
|
rest.Get(prefix+"/health-check", GetSystemHealthStatus),
|
|
rest.Get(prefix+"/orgs/:orgId/budget", auth.RequireAuth(GetBudget)),
|
|
rest.Post(prefix+"/orgs/:orgId/budget", auth.RequireAuth(PostBudget)),
|
|
rest.Delete(prefix+"/orgs/:orgId/budget", auth.RequireAuth(DeleteBudget)),
|
|
)
|
|
}
|