0.1.18 acf151a

sessions.go RawHistoryFolder

1package queries
2
3import (
4	"database/sql"
5	"fmt"
6	"time"
7
8	"github.com/bnema/gordon/internal/db"
9	"github.com/bnema/gordon/internal/server"
10)
11
12// createSession creates a session for the user.
13func createDBSession(a *server.App, browserInfo string, accessToken string, accountID string) error {
14	expireTime := time.Now().Add(time.Hour * 24).Format(time.RFC3339)
15	sessions := &db.Sessions{
16		ID:          generateUUID(),
17		AccessToken: accessToken,
18	}
19
20	query := "INSERT INTO sessions (id, account_id, access_token, browser_info, expires, is_online) VALUES (?, ?, ?, ?, ?, ?)"
21	_, err := a.DB.Exec(query, sessions.ID, accountID, accessToken, browserInfo, expireTime, true)
22	if err != nil {
23		return err
24	}
25
26	// Update global state here if really necessary
27	a.DBTables.Sessions.ID = sessions.ID
28	a.DBTables.Sessions.AccessToken = accessToken
29	a.DBTables.Sessions.Expires = expireTime
30
31	return nil
32}
33
34// GetDBUserSession gets the user session from the database based on the access token and browser info.
35func GetDBUserSession(a *server.App, accessToken string, browserInfo string) (*db.Sessions, error) {
36	query := "SELECT sessions.id, sessions.account_id, sessions.access_token, sessions.browser_info, sessions.expires, sessions.is_online FROM sessions INNER JOIN account ON sessions.account_id = account.id INNER JOIN provider ON account.id = provider.account_id WHERE sessions.access_token = ? AND sessions.browser_info = ?"
37	err := a.DB.QueryRow(query, accessToken, browserInfo).Scan(&a.DBTables.Sessions.ID, &a.DBTables.Sessions.AccountID, &a.DBTables.Sessions.AccessToken, &a.DBTables.Sessions.BrowserInfo, &a.DBTables.Sessions.Expires, &a.DBTables.Sessions.IsOnline)
38	if err != nil {
39		if err == sql.ErrNoRows {
40			return nil, nil
41		}
42		return nil, fmt.Errorf("error getting session: %w", err)
43	}
44
45	return &a.DBTables.Sessions, nil
46}
47
48func updateDBSession(a *server.App, accessToken string, browserInfo string) error {
49	expireTime := time.Now().Add(time.Hour * 24).Format(time.RFC3339)
50	query := "UPDATE sessions SET access_token = ?, expires = ? WHERE id = ?"
51	_, err := a.DB.Exec(query, accessToken, expireTime, a.DBTables.Sessions.ID)
52	if err != nil {
53		return err
54	}
55
56	return nil
57}
58
59func CreateOrUpdateDBSession(a *server.App, accessToken string, browserInfo string) error {
60	// Check if the session exists using the access token and browser info
61	session, err := GetDBUserSession(a, accessToken, browserInfo)
62	if err != nil && err != sql.ErrNoRows {
63		return fmt.Errorf("error checking for session: %w", err)
64	}
65
66	// If the session exists, update the session
67	if session != nil {
68		err := updateDBSession(a, accessToken, browserInfo)
69		if err != nil {
70			return fmt.Errorf("error updating session: %w", err)
71		}
72	}
73
74	// If the session does not exist, create the session
75	if session == nil {
76		err := createDBSession(a, browserInfo, accessToken, a.DBTables.Account.ID)
77		if err != nil {
78			return fmt.Errorf("error creating session: %w", err)
79		}
80	}
81
82	return nil
83}
84
85// DeleteSession deletes the session from the database.
86func DeleteDBSession(a *server.App, accountID string, sessionID string) error {
87	query := "DELETE FROM sessions WHERE account_id = ? AND id = ?"
88	_, err := a.DB.Exec(query, accountID, sessionID)
89	if err != nil {
90		return err
91	}
92
93	return nil
94}
95
96func GetSessionExpiration(a *server.App, accountID string, sessionID string, currentTime time.Time) (time.Time, error) {
97	var expirationTime string
98	// with userID and sessionID we can get the expiration time
99	query := "SELECT expires FROM sessions WHERE account_id = ? AND id = ?"
100	err := a.DB.QueryRow(query, accountID, sessionID).Scan(&expirationTime)
101	if err != nil {
102		return currentTime, err
103	}
104
105	// convert the expiration time to a time.Time
106	expirationTimeParsed, err := time.Parse(time.RFC3339, expirationTime)
107	if err != nil {
108		return currentTime, err
109	}
110
111	return expirationTimeParsed, nil
112}
113
114func ExtendSessionExpiration(a *server.App, accountID string, sessionID string, newExpirationTime time.Time) error {
115	query := "UPDATE sessions SET expires = ? WHERE account_id = ? AND id = ?"
116	_, err := a.DB.Exec(query, newExpirationTime.Format(time.RFC3339), accountID, sessionID)
117	if err != nil {
118		return err
119	}
120
121	return nil
122}
123
124func CheckDBSessionExists(a *server.App, sessionID string) (bool, error) {
125	var sessionExists bool
126	query := "SELECT EXISTS(SELECT 1 FROM sessions WHERE id = ?)"
127	err := a.DB.QueryRow(query, sessionID).Scan(&sessionExists)
128	if err != nil {
129		return false, err
130	}
131
132	return sessionExists, nil
133}
134
135func InvalidateDBSession(a *server.App, sessionID string) error {
136	query := "UPDATE sessions SET is_online = ? WHERE id = ?"
137	_, err := a.DB.Exec(query, false, sessionID)
138	if err != nil {
139		return err
140	}
141
142	return nil
143}

Keyboard shortcuts

Single-key shortcuts are on. ctrl k and esc work whatever this says.

ctrl k :
go to a section, branch, tag, file or repository
?
this list
j k
move the row cursor down / up
enter
open the row under the cursor; on Files, a directory opens or closes in place
↑ ↓ ← → home end
in the file tree (focus on a row): previous / next row, close / open a directory or go to its parent / first entry, first / last row. They never open a file
l h
on Files: open a directory or a file / close a directory or go up to its parent, then to the parent page. Elsewhere: into the side panel (on a merge request, its files) / back to the content; there j k move between its controls
g g G
first / last row
/
filter the list; on Files, find a file anywhere in the repository (esc clears, enter opens the best match)
b
switch branch or tag
g s g f g c g b g m g i g r g a
tabs: summary, files, commits, branches & tags, merge requests, issues, releases, actions (when available)
g h
home
w
wide mode: use the whole width of the screen, or not (remembered)
y
copy a permalink pinned to the commit
d u x
diff: split / unified / collapse or expand all
e E
diff: the whole file in view / every file, with the lines the hunks hide
n
merge request: next note in the diff
esc
close a dialog, leave a field

Branches 7

Tags 106

↑↓ moveenter openesc close