mirror of
https://github.com/fleetdm/fleet
synced 2026-04-21 13:37:30 +00:00
extend the expiration date for the auth token cookie (#41261)
**Related issue:** Resolves #41262 This extends the expiration date for the host auth token cookie. # Checklist for submitter - [x] Changes file added for user-visible changes in `changes/`, `orbit/changes/` or `ee/fleetd-chrome/changes`. - [x] QA'd all new/changed functionality manually
This commit is contained in:
parent
46f8cf4b12
commit
aefad76342
10 changed files with 86 additions and 14 deletions
1
changes/issue-41262-update-authtoken-expiry
Normal file
1
changes/issue-41262-update-authtoken-expiry
Normal file
|
|
@ -0,0 +1 @@
|
|||
- Updated expiration date of the auth token cookie to match the fleet session duration
|
||||
|
|
@ -120,9 +120,12 @@ const LoginPage = ({ router, location }: ILoginPageProps) => {
|
|||
|
||||
try {
|
||||
const response = await sessionsAPI.login(formData);
|
||||
const { user, available_teams, token } = response;
|
||||
const { user, available_teams, token, token_expires_at } = response;
|
||||
|
||||
authToken.save(token);
|
||||
const expiresAt = token_expires_at
|
||||
? new Date(token_expires_at)
|
||||
: undefined;
|
||||
authToken.save(token, expiresAt);
|
||||
|
||||
setCurrentUser(user);
|
||||
setAvailableTeams(user, available_teams);
|
||||
|
|
|
|||
|
|
@ -33,10 +33,16 @@ const LoginPreviewPage = ({ router }: ILoginPreviewPageProps): JSX.Element => {
|
|||
const { DASHBOARD } = paths;
|
||||
|
||||
try {
|
||||
const { user, available_teams, token } = await sessionsAPI.login(
|
||||
formData
|
||||
);
|
||||
authToken.save(token);
|
||||
const {
|
||||
user,
|
||||
available_teams,
|
||||
token,
|
||||
token_expires_at,
|
||||
} = await sessionsAPI.login(formData);
|
||||
const expiresAt = token_expires_at
|
||||
? new Date(token_expires_at)
|
||||
: undefined;
|
||||
authToken.save(token, expiresAt);
|
||||
|
||||
setCurrentUser(user);
|
||||
setAvailableTeams(user, available_teams);
|
||||
|
|
|
|||
|
|
@ -43,9 +43,12 @@ const MfaPage = ({ router, params }: IMfaPage) => {
|
|||
|
||||
try {
|
||||
const response = await sessionsAPI.finishMFA({ token: mfaToken });
|
||||
const { user, available_teams, token } = response;
|
||||
const { user, available_teams, token, token_expires_at } = response;
|
||||
|
||||
authToken.save(token);
|
||||
const expiresAt = token_expires_at
|
||||
? new Date(token_expires_at)
|
||||
: undefined;
|
||||
authToken.save(token, expiresAt);
|
||||
|
||||
setCurrentUser(user);
|
||||
setAvailableTeams(user, available_teams);
|
||||
|
|
|
|||
|
|
@ -23,6 +23,7 @@ export interface ILoginResponse {
|
|||
available_teams: ITeamSummary[];
|
||||
available_fleets: ITeamSummary[];
|
||||
token: string;
|
||||
token_expires_at?: string;
|
||||
}
|
||||
|
||||
export default {
|
||||
|
|
|
|||
|
|
@ -4,8 +4,14 @@
|
|||
*/
|
||||
import Cookie from "js-cookie";
|
||||
|
||||
const save = (token: string): void => {
|
||||
Cookie.set("__Host-token", token, { secure: true, sameSite: "lax" });
|
||||
const DEFAULT_EXPIRATION_DAYS = 5;
|
||||
|
||||
const save = (token: string, expiresAt?: Date): void => {
|
||||
Cookie.set("__Host-token", token, {
|
||||
secure: true,
|
||||
sameSite: "lax",
|
||||
expires: expiresAt ?? DEFAULT_EXPIRATION_DAYS,
|
||||
});
|
||||
};
|
||||
|
||||
const get = (): string | null => {
|
||||
|
|
@ -13,9 +19,12 @@ const get = (): string | null => {
|
|||
};
|
||||
|
||||
const remove = (): void => {
|
||||
// NOTE: the entire cookie including the name and values must be provided
|
||||
// NOTE: the secure and sameSite from the cookie must be provided
|
||||
// to correctly remove. That is why we include the options here as well.
|
||||
Cookie.remove("__Host-token", { secure: true, sameSite: "lax" });
|
||||
Cookie.remove("__Host-token", {
|
||||
secure: true,
|
||||
sameSite: "lax",
|
||||
});
|
||||
};
|
||||
|
||||
export default {
|
||||
|
|
|
|||
|
|
@ -240,6 +240,8 @@ type Service interface {
|
|||
// SSOSettings returns non-sensitive single sign on information used before authentication
|
||||
SSOSettings(ctx context.Context) (*SessionSSOSettings, error)
|
||||
Login(ctx context.Context, email, password string, supportsEmailVerification bool) (user *User, session *Session, err error)
|
||||
// GetSessionDuration returns the configured session duration
|
||||
GetSessionDuration(ctx context.Context) time.Duration
|
||||
Logout(ctx context.Context) (err error)
|
||||
CompleteMFA(ctx context.Context, token string) (*Session, *User, error)
|
||||
DestroySession(ctx context.Context) (err error)
|
||||
|
|
|
|||
|
|
@ -111,6 +111,8 @@ type SSOSettingsFunc func(ctx context.Context) (*fleet.SessionSSOSettings, error
|
|||
|
||||
type LoginFunc func(ctx context.Context, email string, password string, supportsEmailVerification bool) (user *fleet.User, session *fleet.Session, err error)
|
||||
|
||||
type GetSessionDurationFunc func(ctx context.Context) time.Duration
|
||||
|
||||
type LogoutFunc func(ctx context.Context) (err error)
|
||||
|
||||
type CompleteMFAFunc func(ctx context.Context, token string) (*fleet.Session, *fleet.User, error)
|
||||
|
|
@ -1026,6 +1028,9 @@ type Service struct {
|
|||
LoginFunc LoginFunc
|
||||
LoginFuncInvoked bool
|
||||
|
||||
GetSessionDurationFunc GetSessionDurationFunc
|
||||
GetSessionDurationFuncInvoked bool
|
||||
|
||||
LogoutFunc LogoutFunc
|
||||
LogoutFuncInvoked bool
|
||||
|
||||
|
|
@ -2515,6 +2520,13 @@ func (s *Service) Login(ctx context.Context, email string, password string, supp
|
|||
return s.LoginFunc(ctx, email, password, supportsEmailVerification)
|
||||
}
|
||||
|
||||
func (s *Service) GetSessionDuration(ctx context.Context) time.Duration {
|
||||
s.mu.Lock()
|
||||
s.GetSessionDurationFuncInvoked = true
|
||||
s.mu.Unlock()
|
||||
return s.GetSessionDurationFunc(ctx)
|
||||
}
|
||||
|
||||
func (s *Service) Logout(ctx context.Context) (err error) {
|
||||
s.mu.Lock()
|
||||
s.LogoutFuncInvoked = true
|
||||
|
|
|
|||
|
|
@ -23,6 +23,10 @@ func (mw metricsMiddleware) Login(ctx context.Context, email string, password st
|
|||
return user, session, err
|
||||
}
|
||||
|
||||
func (mw metricsMiddleware) GetSessionDuration(ctx context.Context) time.Duration {
|
||||
return mw.Service.GetSessionDuration(ctx)
|
||||
}
|
||||
|
||||
func (mw metricsMiddleware) Logout(ctx context.Context) error {
|
||||
var err error
|
||||
defer func(begin time.Time) {
|
||||
|
|
|
|||
|
|
@ -120,6 +120,7 @@ type loginResponse struct {
|
|||
User *fleet.User `json:"user,omitempty"`
|
||||
AvailableTeams []*fleet.TeamSummary `json:"available_teams" renameto:"available_fleets"`
|
||||
Token string `json:"token,omitempty"`
|
||||
TokenExpiresAt *time.Time `json:"token_expires_at,omitempty"`
|
||||
Err error `json:"error,omitempty"`
|
||||
}
|
||||
|
||||
|
|
@ -159,7 +160,20 @@ func loginEndpoint(ctx context.Context, request interface{}, svc fleet.Service)
|
|||
return loginResponse{Err: err}, nil
|
||||
}
|
||||
}
|
||||
return loginResponse{user, availableTeams, session.Key, nil}, nil
|
||||
|
||||
// Calculate token expiration time if session duration is configured
|
||||
var tokenExpiresAt *time.Time
|
||||
if sessionDuration := svc.GetSessionDuration(ctx); sessionDuration > 0 {
|
||||
expiresAt := time.Now().Add(sessionDuration).UTC()
|
||||
tokenExpiresAt = &expiresAt
|
||||
}
|
||||
|
||||
return loginResponse{
|
||||
User: user,
|
||||
AvailableTeams: availableTeams,
|
||||
Token: session.Key,
|
||||
TokenExpiresAt: tokenExpiresAt,
|
||||
}, nil
|
||||
}
|
||||
|
||||
var (
|
||||
|
|
@ -254,6 +268,10 @@ func (svc *Service) makeSession(ctx context.Context, userID uint) (*fleet.Sessio
|
|||
return svc.ds.NewSession(ctx, userID, svc.config.Session.KeySize)
|
||||
}
|
||||
|
||||
func (svc *Service) GetSessionDuration(ctx context.Context) time.Duration {
|
||||
return svc.config.Session.Duration
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// Session create (second step of MFA)
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
|
@ -281,7 +299,20 @@ func sessionCreateEndpoint(ctx context.Context, request interface{}, svc fleet.S
|
|||
return loginResponse{Err: err}, nil
|
||||
}
|
||||
}
|
||||
return loginResponse{user, availableTeams, session.Key, nil}, nil
|
||||
|
||||
// Calculate token expiration time if session duration is configured
|
||||
var tokenExpiresAt *time.Time
|
||||
if sessionDuration := svc.GetSessionDuration(ctx); sessionDuration > 0 {
|
||||
expiresAt := time.Now().Add(sessionDuration).UTC()
|
||||
tokenExpiresAt = &expiresAt
|
||||
}
|
||||
|
||||
return loginResponse{
|
||||
User: user,
|
||||
AvailableTeams: availableTeams,
|
||||
Token: session.Key,
|
||||
TokenExpiresAt: tokenExpiresAt,
|
||||
}, nil
|
||||
}
|
||||
|
||||
func (svc *Service) CompleteMFA(ctx context.Context, token string) (*fleet.Session, *fleet.User, error) {
|
||||
|
|
|
|||
Loading…
Reference in a new issue