token="" => unset
(ctx context.Context, stores *store.Store, licenseService *enterprise.LicenseService, workspaceID string, origin, token string)
| 13 | |
| 14 | // token="" => unset |
| 15 | func GetTokenCookie(ctx context.Context, stores *store.Store, licenseService *enterprise.LicenseService, workspaceID string, origin, token string) *http.Cookie { |
| 16 | if token == "" { |
| 17 | return &http.Cookie{ |
| 18 | Name: AccessTokenCookieName, |
| 19 | Value: "", |
| 20 | Expires: time.Unix(0, 0), |
| 21 | Path: "/", |
| 22 | } |
| 23 | } |
| 24 | isHTTPS := strings.HasPrefix(origin, "https") |
| 25 | // Cookie expiry matches the refresh token duration so that Refresh() can always |
| 26 | // extract the workspace from the expired JWT, even after long idle periods. |
| 27 | // The auth middleware rejects expired JWTs for API calls, so a stale cookie is harmless. |
| 28 | // The cookie is only read by Refresh() which verifies the signature but skips expiry. |
| 29 | cookieDuration := GetRefreshTokenDuration(ctx, stores, licenseService, workspaceID) |
| 30 | return &http.Cookie{ |
| 31 | Name: AccessTokenCookieName, |
| 32 | Value: token, |
| 33 | Expires: time.Now().Add(cookieDuration), |
| 34 | Path: "/", |
| 35 | // Http-only helps mitigate the risk of client side script accessing the protected cookie. |
| 36 | HttpOnly: true, |
| 37 | // See https://github.com/bytebase/bytebase/issues/31. |
| 38 | Secure: isHTTPS, |
| 39 | SameSite: http.SameSiteStrictMode, |
| 40 | } |
| 41 | } |
| 42 | |
| 43 | func GetAccessTokenDuration(ctx context.Context, store *store.Store, licenseService *enterprise.LicenseService, workspaceID string) time.Duration { |
| 44 | accessTokenDuration := DefaultAccessTokenDuration |
no test coverage detected