diff --git a/proto/src/internal/error.rs b/proto/src/internal/error.rs index 75a7d5711..2fe30a42a 100644 --- a/proto/src/internal/error.rs +++ b/proto/src/internal/error.rs @@ -268,6 +268,7 @@ pub enum OperationError { // Web UI UI0001ChallengeSerialisation, UI0002InvalidState, + UI0003InvalidOauth2Resume, // Unixd Things KU001InitWhileSessionActive, @@ -457,25 +458,26 @@ impl OperationError { Self::SC0009IndexTypeSyntaxInvalid => Some("A SCIM IndexType contained invalid syntax".into()), Self::SC0010DateTimeSyntaxInvalid => Some("A SCIM DateTime contained invalid syntax".into()), - Self::SC0011AddressSyntaxInvalid => Some("A SCIM Address contained invalid syntax".into()), - Self::SC0012CertificateSyntaxInvalid => Some("A SCIM Certificate contained invalid binary data".into()), - Self::SC0013CertificateInvalidDer => Some("A SCIM Certificate did not contain valid DER".into()), - Self::SC0014CertificateInvalidDigest => Some("A SCIM Certificate was unable to be digested".into()), - Self::SC0015CredentialTypeSyntaxInvalid => Some("A SCIM CredentialType contained invalid syntax".into()), - Self::SC0016InameSyntaxInvalid => Some("A SCIM Iname string contained invalid syntax".into()), - Self::SC0017Iutf8SyntaxInvalid => Some("A SCIM Iutf8 string contained invalid syntax".into()), - Self::SC0018NsUniqueIdSyntaxInvalid => Some("A SCIM NsUniqueID contained invalid syntax".into()), - Self::SC0019Oauth2ScopeSyntaxInvalid => Some("A SCIM Oauth2 Scope contained invalid syntax".into()), - Self::SC0020Oauth2ScopeMapSyntaxInvalid => Some("A SCIM Oauth2 Scope Map contained invalid syntax".into()), - Self::SC0021Oauth2ScopeMapMissingGroupIdentifier => Some("A SCIM Oauth2 Scope Map was missing a group name or uuid".into()), - Self::SC0022Oauth2ClaimMapSyntaxInvalid => Some("A SCIM Oauth2 Claim Map contained invalid syntax".into()), - Self::SC0023Oauth2ClaimMapMissingGroupIdentifier => Some("A SCIM Claim Map was missing a group name or uuid".into()), - Self::SC0024SshPublicKeySyntaxInvalid => Some("A SCIM Ssh Public Key contained invalid syntax".into()), - Self::SC0025UiHintSyntaxInvalid => Some("A SCIM UiHint contained invalid syntax".into()), - Self::SC0026Utf8SyntaxInvalid => Some("A SCIM Utf8 String Scope Map contained invalid syntax".into()), + Self::SC0011AddressSyntaxInvalid => Some("A SCIM Address contained invalid syntax".into()), + Self::SC0012CertificateSyntaxInvalid => Some("A SCIM Certificate contained invalid binary data".into()), + Self::SC0013CertificateInvalidDer => Some("A SCIM Certificate did not contain valid DER".into()), + Self::SC0014CertificateInvalidDigest => Some("A SCIM Certificate was unable to be digested".into()), + Self::SC0015CredentialTypeSyntaxInvalid => Some("A SCIM CredentialType contained invalid syntax".into()), + Self::SC0016InameSyntaxInvalid => Some("A SCIM Iname string contained invalid syntax".into()), + Self::SC0017Iutf8SyntaxInvalid => Some("A SCIM Iutf8 string contained invalid syntax".into()), + Self::SC0018NsUniqueIdSyntaxInvalid => Some("A SCIM NsUniqueID contained invalid syntax".into()), + Self::SC0019Oauth2ScopeSyntaxInvalid => Some("A SCIM Oauth2 Scope contained invalid syntax".into()), + Self::SC0020Oauth2ScopeMapSyntaxInvalid => Some("A SCIM Oauth2 Scope Map contained invalid syntax".into()), + Self::SC0021Oauth2ScopeMapMissingGroupIdentifier => Some("A SCIM Oauth2 Scope Map was missing a group name or uuid".into()), + Self::SC0022Oauth2ClaimMapSyntaxInvalid => Some("A SCIM Oauth2 Claim Map contained invalid syntax".into()), + Self::SC0023Oauth2ClaimMapMissingGroupIdentifier => Some("A SCIM Claim Map was missing a group name or uuid".into()), + Self::SC0024SshPublicKeySyntaxInvalid => Some("A SCIM Ssh Public Key contained invalid syntax".into()), + Self::SC0025UiHintSyntaxInvalid => Some("A SCIM UiHint contained invalid syntax".into()), + Self::SC0026Utf8SyntaxInvalid => Some("A SCIM Utf8 String Scope Map contained invalid syntax".into()), Self::UI0001ChallengeSerialisation => Some("The WebAuthn challenge was unable to be serialised.".into()), Self::UI0002InvalidState => Some("The credential update process returned an invalid state transition.".into()), + Self::UI0003InvalidOauth2Resume => Some("The server attemped to resume OAuth2, but no OAuth2 session is in progress.".into()), Self::VL0001ValueSshPublicKeyString => None, Self::VS0001IncomingReplSshPublicKey => None, Self::VS0002CertificatePublicKeyDigest | diff --git a/server/core/src/https/views/cookies.rs b/server/core/src/https/views/cookies.rs index be2f817c8..7b1abc00e 100644 --- a/server/core/src/https/views/cookies.rs +++ b/server/core/src/https/views/cookies.rs @@ -10,11 +10,6 @@ pub fn destroy(jar: CookieJar, ck_id: &str) -> CookieJar { if let Some(ck) = jar.get(ck_id) { let mut ck = ck.clone(); ck.make_removal(); - /* - if let Some(path) = ck.path().cloned() { - ck.set_path(&path); - } - */ jar.add(ck) } else { jar @@ -37,8 +32,6 @@ pub fn make_unsigned<'a>( // then webauthn won't work anyway! token_cookie.set_domain(state.domain.clone()); token_cookie.set_path(path); - // These last forever. - token_cookie.make_permanent(); token_cookie } @@ -71,8 +64,6 @@ pub fn make_signed<'a, T: Serialize>( token_cookie.set_http_only(true); token_cookie.set_path(path); token_cookie.set_domain(state.domain.clone()); - // These last forever, we have our own internal expiration handling. - token_cookie.make_permanent(); Some(token_cookie) } diff --git a/server/core/src/https/views/login.rs b/server/core/src/https/views/login.rs index 3b5c2b6ba..da8d3fee3 100644 --- a/server/core/src/https/views/login.rs +++ b/server/core/src/https/views/login.rs @@ -926,22 +926,25 @@ async fn view_login_step( // Important - this can be make unsigned as token_str has it's own // signatures. - let bearer_cookie = cookies::make_unsigned( + let mut bearer_cookie = cookies::make_unsigned( &state, COOKIE_BEARER_TOKEN, token_str.clone(), "/", ); + // Important - can be permanent as the token has its own expiration time internally + bearer_cookie.make_permanent(); jar = if session_context.remember_me { // Important - can be unsigned as username is just for remember // me and no other purpose. - let username_cookie = cookies::make_unsigned( + let mut username_cookie = cookies::make_unsigned( &state, COOKIE_USERNAME, session_context.username.clone(), Urls::Login.as_ref(), ); + username_cookie.make_permanent(); jar.add(username_cookie) } else { jar diff --git a/server/core/src/https/views/oauth2.rs b/server/core/src/https/views/oauth2.rs index bea06985c..982f2414d 100644 --- a/server/core/src/https/views/oauth2.rs +++ b/server/core/src/https/views/oauth2.rs @@ -112,7 +112,7 @@ async fn oauth2_auth_req( return ( jar, UnrecoverableErrorView { - err_code: OperationError::InvalidState, + err_code: OperationError::UI0003InvalidOauth2Resume, operation_id: kopid.eventid, }, ) @@ -176,6 +176,10 @@ async fn oauth2_auth_req( cookies::make_signed(&state, COOKIE_OAUTH2_REQ, &auth_req, Urls::Ui.as_ref()) .map(|mut cookie| { cookie.set_same_site(SameSite::Strict); + // Expire at the end of the session. + cookie.set_expires(None); + // Could experiment with this to a shorter value, but session should be enough. + cookie.set_max_age(None); jar.add(cookie) }) .ok_or(OperationError::InvalidSessionState);