fix: audit round 2 — session cookie Secure kondisional, logout clear cookie, IDOR report owner-scoping (migrasi 0008), health force login-gate, SSE stream login-gate, FE: Gate undefined-flicker, auth-expired global redirect, X-User-Key demo dihapus, error handling alerts/routines/watchlist, chart label, encodeURIComponent, Screener onMount
This commit is contained in:
@@ -23,6 +23,7 @@ const (
|
||||
ErrBadPassword authErr = "password minimal 8 karakter"
|
||||
ErrTaken authErr = "username sudah dipakai"
|
||||
)
|
||||
|
||||
type User struct {
|
||||
ID int64
|
||||
GoogleSub string
|
||||
|
||||
@@ -0,0 +1,16 @@
|
||||
-- 0008_reports_owner.sql: reports now scoped to the owning user.
|
||||
-- Existing rows are assigned to the shared demo key so historic reports
|
||||
-- remain readable by the demo/seed pipeline; new reports carry user_key.
|
||||
CREATE TABLE IF NOT EXISTS reports_new(
|
||||
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
||||
ticker TEXT NOT NULL, generated_at TEXT NOT NULL,
|
||||
payload_json TEXT NOT NULL, citations_json TEXT NOT NULL DEFAULT '[]',
|
||||
user_key TEXT NOT NULL DEFAULT 'demo'
|
||||
);
|
||||
INSERT INTO reports_new(id, ticker, generated_at, payload_json, citations_json, user_key)
|
||||
SELECT id, ticker, generated_at, payload_json, citations_json, 'demo' FROM reports;
|
||||
DROP TABLE reports;
|
||||
ALTER TABLE reports_new RENAME TO reports;
|
||||
CREATE INDEX IF NOT EXISTS idx_reports_ticker ON reports(ticker, id);
|
||||
|
||||
-- SQLite ignores IF NOT EXISTS on column add; guard on table existence.
|
||||
@@ -611,10 +611,10 @@ func (db *DB) FilingsSince(ticker, since string, limit int) ([]map[string]any, e
|
||||
|
||||
// Reports reports / briefings.
|
||||
|
||||
// SaveReport stores a generated report; returns its id.
|
||||
func (db *DB) SaveReport(ticker, payload, cites string) (int64, error) {
|
||||
res, err := db.Exec(`INSERT INTO reports(ticker,generated_at,payload_json,citations_json)
|
||||
VALUES(?,?,?,?)`, ticker, time.Now().UTC().Format(time.RFC3339), payload, cites)
|
||||
// SaveReport stores a generated report owned by userKey; returns its id.
|
||||
func (db *DB) SaveReport(ticker, payload, cites, userKey string) (int64, error) {
|
||||
res, err := db.Exec(`INSERT INTO reports(ticker,generated_at,payload_json,citations_json,user_key)
|
||||
VALUES(?,?,?,?,?)`, ticker, time.Now().UTC().Format(time.RFC3339), payload, cites, userKey)
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
|
||||
@@ -50,7 +50,7 @@ func TestStoreParity(t *testing.T) {
|
||||
if err != nil || len(fils) != 1 {
|
||||
t.Fatalf("filings = %v, %v", fils, err)
|
||||
}
|
||||
_, _ = db.SaveReport("BBCA", `{"a":1}`, `[]`)
|
||||
_, _ = db.SaveReport("BBCA", `{"a":1}`, `[]`, "tester")
|
||||
reps, err := db.ListReports("BBCA", 10)
|
||||
if err != nil || len(reps) != 1 {
|
||||
t.Fatalf("reports = %v, %v", reps, err)
|
||||
|
||||
Reference in New Issue
Block a user