You've already forked authentication-service
mirror of
https://github.com/matrix-org/matrix-authentication-service.git
synced 2025-07-29 22:01:14 +03:00
Make the last activity timestamp and IP available through the API
This commit is contained in:
@ -12,6 +12,8 @@
|
|||||||
// See the License for the specific language governing permissions and
|
// See the License for the specific language governing permissions and
|
||||||
// limitations under the License.
|
// limitations under the License.
|
||||||
|
|
||||||
|
use std::net::IpAddr;
|
||||||
|
|
||||||
use chrono::{DateTime, Utc};
|
use chrono::{DateTime, Utc};
|
||||||
use serde::Serialize;
|
use serde::Serialize;
|
||||||
use ulid::Ulid;
|
use ulid::Ulid;
|
||||||
@ -80,6 +82,8 @@ pub struct CompatSession {
|
|||||||
pub device: Device,
|
pub device: Device,
|
||||||
pub created_at: DateTime<Utc>,
|
pub created_at: DateTime<Utc>,
|
||||||
pub is_synapse_admin: bool,
|
pub is_synapse_admin: bool,
|
||||||
|
pub last_active_at: Option<DateTime<Utc>>,
|
||||||
|
pub last_active_ip: Option<IpAddr>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl std::ops::Deref for CompatSession {
|
impl std::ops::Deref for CompatSession {
|
||||||
|
@ -12,6 +12,7 @@
|
|||||||
// See the License for the specific language governing permissions and
|
// See the License for the specific language governing permissions and
|
||||||
// limitations under the License.
|
// limitations under the License.
|
||||||
|
|
||||||
|
use std::net::IpAddr;
|
||||||
use chrono::{DateTime, Utc};
|
use chrono::{DateTime, Utc};
|
||||||
use oauth2_types::scope::Scope;
|
use oauth2_types::scope::Scope;
|
||||||
use serde::Serialize;
|
use serde::Serialize;
|
||||||
@ -73,6 +74,8 @@ pub struct Session {
|
|||||||
pub user_session_id: Option<Ulid>,
|
pub user_session_id: Option<Ulid>,
|
||||||
pub client_id: Ulid,
|
pub client_id: Ulid,
|
||||||
pub scope: Scope,
|
pub scope: Scope,
|
||||||
|
pub last_active_at: Option<DateTime<Utc>>,
|
||||||
|
pub last_active_ip: Option<IpAddr>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl std::ops::Deref for Session {
|
impl std::ops::Deref for Session {
|
||||||
|
@ -12,7 +12,7 @@
|
|||||||
// See the License for the specific language governing permissions and
|
// See the License for the specific language governing permissions and
|
||||||
// limitations under the License.
|
// limitations under the License.
|
||||||
|
|
||||||
use std::ops::Deref;
|
use std::{net::IpAddr, ops::Deref};
|
||||||
|
|
||||||
use chrono::{DateTime, Duration, Utc};
|
use chrono::{DateTime, Duration, Utc};
|
||||||
use rand::{Rng, SeedableRng};
|
use rand::{Rng, SeedableRng};
|
||||||
@ -81,6 +81,8 @@ pub struct BrowserSession {
|
|||||||
pub created_at: DateTime<Utc>,
|
pub created_at: DateTime<Utc>,
|
||||||
pub finished_at: Option<DateTime<Utc>>,
|
pub finished_at: Option<DateTime<Utc>>,
|
||||||
pub user_agent: Option<String>,
|
pub user_agent: Option<String>,
|
||||||
|
pub last_active_at: Option<DateTime<Utc>>,
|
||||||
|
pub last_active_ip: Option<IpAddr>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl BrowserSession {
|
impl BrowserSession {
|
||||||
@ -101,6 +103,8 @@ impl BrowserSession {
|
|||||||
created_at: now,
|
created_at: now,
|
||||||
finished_at: None,
|
finished_at: None,
|
||||||
user_agent: Some("Mozilla/5.0".to_owned()),
|
user_agent: Some("Mozilla/5.0".to_owned()),
|
||||||
|
last_active_at: Some(now),
|
||||||
|
last_active_ip: None,
|
||||||
})
|
})
|
||||||
.collect()
|
.collect()
|
||||||
}
|
}
|
||||||
|
@ -92,6 +92,16 @@ impl BrowserSession {
|
|||||||
pub async fn user_agent(&self) -> Option<&str> {
|
pub async fn user_agent(&self) -> Option<&str> {
|
||||||
self.0.user_agent.as_deref()
|
self.0.user_agent.as_deref()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// The last IP address used by the session.
|
||||||
|
pub async fn last_active_ip(&self) -> Option<String> {
|
||||||
|
self.0.last_active_ip.map(|ip| ip.to_string())
|
||||||
|
}
|
||||||
|
|
||||||
|
/// The last time the session was active.
|
||||||
|
pub async fn last_active_at(&self) -> Option<DateTime<Utc>> {
|
||||||
|
self.0.last_active_at
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// An authentication records when a user enter their credential in a browser
|
/// An authentication records when a user enter their credential in a browser
|
||||||
|
@ -142,6 +142,16 @@ impl CompatSession {
|
|||||||
mas_data_model::CompatSessionState::Finished { .. } => CompatSessionState::Finished,
|
mas_data_model::CompatSessionState::Finished { .. } => CompatSessionState::Finished,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// The last IP address used by the session.
|
||||||
|
pub async fn last_active_ip(&self) -> Option<String> {
|
||||||
|
self.session.last_active_ip.map(|ip| ip.to_string())
|
||||||
|
}
|
||||||
|
|
||||||
|
/// The last time the session was active.
|
||||||
|
pub async fn last_active_at(&self) -> Option<DateTime<Utc>> {
|
||||||
|
self.session.last_active_at
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// A compat SSO login represents a login done through the legacy Matrix login
|
/// A compat SSO login represents a login done through the legacy Matrix login
|
||||||
|
@ -128,6 +128,16 @@ impl OAuth2Session {
|
|||||||
|
|
||||||
Ok(Some(User(user)))
|
Ok(Some(User(user)))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// The last IP address used by the session.
|
||||||
|
pub async fn last_active_ip(&self) -> Option<String> {
|
||||||
|
self.0.last_active_ip.map(|ip| ip.to_string())
|
||||||
|
}
|
||||||
|
|
||||||
|
/// The last time the session was active.
|
||||||
|
pub async fn last_active_at(&self) -> Option<DateTime<Utc>> {
|
||||||
|
self.0.last_active_at
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// The application type advertised by the client.
|
/// The application type advertised by the client.
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"db_name": "PostgreSQL",
|
"db_name": "PostgreSQL",
|
||||||
"query": "\n SELECT compat_session_id\n , device_id\n , user_id\n , created_at\n , finished_at\n , is_synapse_admin\n FROM compat_sessions\n WHERE compat_session_id = $1\n ",
|
"query": "\n SELECT compat_session_id\n , device_id\n , user_id\n , created_at\n , finished_at\n , is_synapse_admin\n , last_active_at\n , last_active_ip as \"last_active_ip: IpAddr\"\n FROM compat_sessions\n WHERE compat_session_id = $1\n ",
|
||||||
"describe": {
|
"describe": {
|
||||||
"columns": [
|
"columns": [
|
||||||
{
|
{
|
||||||
@ -32,6 +32,16 @@
|
|||||||
"ordinal": 5,
|
"ordinal": 5,
|
||||||
"name": "is_synapse_admin",
|
"name": "is_synapse_admin",
|
||||||
"type_info": "Bool"
|
"type_info": "Bool"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"ordinal": 6,
|
||||||
|
"name": "last_active_at",
|
||||||
|
"type_info": "Timestamptz"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"ordinal": 7,
|
||||||
|
"name": "last_active_ip: IpAddr",
|
||||||
|
"type_info": "Inet"
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"parameters": {
|
"parameters": {
|
||||||
@ -45,8 +55,10 @@
|
|||||||
false,
|
false,
|
||||||
false,
|
false,
|
||||||
true,
|
true,
|
||||||
false
|
false,
|
||||||
|
true,
|
||||||
|
true
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
"hash": "0469c1d3ad11fd96febacad33302709c870ead848d6920cdfdb18912d543488e"
|
"hash": "23c03635d6433099a4353ba0c80b88737724edb16315832891550e29088d02bf"
|
||||||
}
|
}
|
@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"db_name": "PostgreSQL",
|
"db_name": "PostgreSQL",
|
||||||
"query": "\n SELECT s.user_session_id\n , s.created_at AS \"user_session_created_at\"\n , s.finished_at AS \"user_session_finished_at\"\n , s.user_agent AS \"user_session_user_agent\"\n , u.user_id\n , u.username AS \"user_username\"\n , u.primary_user_email_id AS \"user_primary_user_email_id\"\n , u.created_at AS \"user_created_at\"\n , u.locked_at AS \"user_locked_at\"\n FROM user_sessions s\n INNER JOIN users u\n USING (user_id)\n WHERE s.user_session_id = $1\n ",
|
"query": "\n SELECT s.user_session_id\n , s.created_at AS \"user_session_created_at\"\n , s.finished_at AS \"user_session_finished_at\"\n , s.user_agent AS \"user_session_user_agent\"\n , s.last_active_at AS \"user_session_last_active_at\"\n , s.last_active_ip AS \"user_session_last_active_ip: IpAddr\"\n , u.user_id\n , u.username AS \"user_username\"\n , u.primary_user_email_id AS \"user_primary_user_email_id\"\n , u.created_at AS \"user_created_at\"\n , u.locked_at AS \"user_locked_at\"\n FROM user_sessions s\n INNER JOIN users u\n USING (user_id)\n WHERE s.user_session_id = $1\n ",
|
||||||
"describe": {
|
"describe": {
|
||||||
"columns": [
|
"columns": [
|
||||||
{
|
{
|
||||||
@ -25,26 +25,36 @@
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
"ordinal": 4,
|
"ordinal": 4,
|
||||||
|
"name": "user_session_last_active_at",
|
||||||
|
"type_info": "Timestamptz"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"ordinal": 5,
|
||||||
|
"name": "user_session_last_active_ip: IpAddr",
|
||||||
|
"type_info": "Inet"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"ordinal": 6,
|
||||||
"name": "user_id",
|
"name": "user_id",
|
||||||
"type_info": "Uuid"
|
"type_info": "Uuid"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"ordinal": 5,
|
"ordinal": 7,
|
||||||
"name": "user_username",
|
"name": "user_username",
|
||||||
"type_info": "Text"
|
"type_info": "Text"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"ordinal": 6,
|
"ordinal": 8,
|
||||||
"name": "user_primary_user_email_id",
|
"name": "user_primary_user_email_id",
|
||||||
"type_info": "Uuid"
|
"type_info": "Uuid"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"ordinal": 7,
|
"ordinal": 9,
|
||||||
"name": "user_created_at",
|
"name": "user_created_at",
|
||||||
"type_info": "Timestamptz"
|
"type_info": "Timestamptz"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"ordinal": 8,
|
"ordinal": 10,
|
||||||
"name": "user_locked_at",
|
"name": "user_locked_at",
|
||||||
"type_info": "Timestamptz"
|
"type_info": "Timestamptz"
|
||||||
}
|
}
|
||||||
@ -59,6 +69,8 @@
|
|||||||
false,
|
false,
|
||||||
true,
|
true,
|
||||||
true,
|
true,
|
||||||
|
true,
|
||||||
|
true,
|
||||||
false,
|
false,
|
||||||
false,
|
false,
|
||||||
true,
|
true,
|
||||||
@ -66,5 +78,5 @@
|
|||||||
true
|
true
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
"hash": "b98052065469a71643bb332cbeb07e0e43c620ffa1a592eb45ab326e0064efa8"
|
"hash": "2b0d54c284dc4d946faae4190568bf597c04b40f010132dd7bf68462c47f9eac"
|
||||||
}
|
}
|
@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"db_name": "PostgreSQL",
|
"db_name": "PostgreSQL",
|
||||||
"query": "\n SELECT oauth2_session_id\n , user_id\n , user_session_id\n , oauth2_client_id\n , scope_list\n , created_at\n , finished_at\n FROM oauth2_sessions\n\n WHERE oauth2_session_id = $1\n ",
|
"query": "\n SELECT oauth2_session_id\n , user_id\n , user_session_id\n , oauth2_client_id\n , scope_list\n , created_at\n , finished_at\n , last_active_at\n , last_active_ip as \"last_active_ip: IpAddr\"\n FROM oauth2_sessions\n\n WHERE oauth2_session_id = $1\n ",
|
||||||
"describe": {
|
"describe": {
|
||||||
"columns": [
|
"columns": [
|
||||||
{
|
{
|
||||||
@ -37,6 +37,16 @@
|
|||||||
"ordinal": 6,
|
"ordinal": 6,
|
||||||
"name": "finished_at",
|
"name": "finished_at",
|
||||||
"type_info": "Timestamptz"
|
"type_info": "Timestamptz"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"ordinal": 7,
|
||||||
|
"name": "last_active_at",
|
||||||
|
"type_info": "Timestamptz"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"ordinal": 8,
|
||||||
|
"name": "last_active_ip: IpAddr",
|
||||||
|
"type_info": "Inet"
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"parameters": {
|
"parameters": {
|
||||||
@ -51,8 +61,10 @@
|
|||||||
false,
|
false,
|
||||||
false,
|
false,
|
||||||
false,
|
false,
|
||||||
|
true,
|
||||||
|
true,
|
||||||
true
|
true
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
"hash": "31b7910705963c1a0fa1d55614299aea1a2fa782d40ec53e93c03fe0d73ab0f4"
|
"hash": "31aace373b20b5dbf65fa51d8663da7571d85b6a7d2d544d69e7d04260cdffc9"
|
||||||
}
|
}
|
@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"db_name": "PostgreSQL",
|
"db_name": "PostgreSQL",
|
||||||
"query": "\n SELECT compat_session_id\n , device_id\n , user_id\n , created_at\n , finished_at\n , is_synapse_admin\n FROM compat_sessions\n WHERE user_id = $1\n AND device_id = $2\n ",
|
"query": "\n SELECT compat_session_id\n , device_id\n , user_id\n , created_at\n , finished_at\n , is_synapse_admin\n , last_active_at\n , last_active_ip as \"last_active_ip: IpAddr\"\n FROM compat_sessions\n WHERE user_id = $1\n AND device_id = $2\n ",
|
||||||
"describe": {
|
"describe": {
|
||||||
"columns": [
|
"columns": [
|
||||||
{
|
{
|
||||||
@ -32,6 +32,16 @@
|
|||||||
"ordinal": 5,
|
"ordinal": 5,
|
||||||
"name": "is_synapse_admin",
|
"name": "is_synapse_admin",
|
||||||
"type_info": "Bool"
|
"type_info": "Bool"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"ordinal": 6,
|
||||||
|
"name": "last_active_at",
|
||||||
|
"type_info": "Timestamptz"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"ordinal": 7,
|
||||||
|
"name": "last_active_ip: IpAddr",
|
||||||
|
"type_info": "Inet"
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"parameters": {
|
"parameters": {
|
||||||
@ -46,8 +56,10 @@
|
|||||||
false,
|
false,
|
||||||
false,
|
false,
|
||||||
true,
|
true,
|
||||||
false
|
false,
|
||||||
|
true,
|
||||||
|
true
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
"hash": "89e8bb889b8e604d1b4669e904d3233e70b44277e7fe2ce4317c9d821512d86b"
|
"hash": "662ff8972c0cbccb9ba45b1d724c7b6e87656beabe702603cfd4b5a92263b5ab"
|
||||||
}
|
}
|
@ -58,6 +58,8 @@ struct CompatSessionLookup {
|
|||||||
created_at: DateTime<Utc>,
|
created_at: DateTime<Utc>,
|
||||||
finished_at: Option<DateTime<Utc>>,
|
finished_at: Option<DateTime<Utc>>,
|
||||||
is_synapse_admin: bool,
|
is_synapse_admin: bool,
|
||||||
|
last_active_at: Option<DateTime<Utc>>,
|
||||||
|
last_active_ip: Option<IpAddr>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl TryFrom<CompatSessionLookup> for CompatSession {
|
impl TryFrom<CompatSessionLookup> for CompatSession {
|
||||||
@ -84,6 +86,8 @@ impl TryFrom<CompatSessionLookup> for CompatSession {
|
|||||||
device,
|
device,
|
||||||
created_at: value.created_at,
|
created_at: value.created_at,
|
||||||
is_synapse_admin: value.is_synapse_admin,
|
is_synapse_admin: value.is_synapse_admin,
|
||||||
|
last_active_at: value.last_active_at,
|
||||||
|
last_active_ip: value.last_active_ip,
|
||||||
};
|
};
|
||||||
|
|
||||||
Ok(session)
|
Ok(session)
|
||||||
@ -99,6 +103,8 @@ struct CompatSessionAndSsoLoginLookup {
|
|||||||
created_at: DateTime<Utc>,
|
created_at: DateTime<Utc>,
|
||||||
finished_at: Option<DateTime<Utc>>,
|
finished_at: Option<DateTime<Utc>>,
|
||||||
is_synapse_admin: bool,
|
is_synapse_admin: bool,
|
||||||
|
last_active_at: Option<DateTime<Utc>>,
|
||||||
|
last_active_ip: Option<IpAddr>,
|
||||||
compat_sso_login_id: Option<Uuid>,
|
compat_sso_login_id: Option<Uuid>,
|
||||||
compat_sso_login_token: Option<String>,
|
compat_sso_login_token: Option<String>,
|
||||||
compat_sso_login_redirect_uri: Option<String>,
|
compat_sso_login_redirect_uri: Option<String>,
|
||||||
@ -131,6 +137,8 @@ impl TryFrom<CompatSessionAndSsoLoginLookup> for (CompatSession, Option<CompatSs
|
|||||||
device,
|
device,
|
||||||
created_at: value.created_at,
|
created_at: value.created_at,
|
||||||
is_synapse_admin: value.is_synapse_admin,
|
is_synapse_admin: value.is_synapse_admin,
|
||||||
|
last_active_at: value.last_active_at,
|
||||||
|
last_active_ip: value.last_active_ip,
|
||||||
};
|
};
|
||||||
|
|
||||||
match (
|
match (
|
||||||
@ -209,6 +217,8 @@ impl<'c> CompatSessionRepository for PgCompatSessionRepository<'c> {
|
|||||||
, created_at
|
, created_at
|
||||||
, finished_at
|
, finished_at
|
||||||
, is_synapse_admin
|
, is_synapse_admin
|
||||||
|
, last_active_at
|
||||||
|
, last_active_ip as "last_active_ip: IpAddr"
|
||||||
FROM compat_sessions
|
FROM compat_sessions
|
||||||
WHERE compat_session_id = $1
|
WHERE compat_session_id = $1
|
||||||
"#,
|
"#,
|
||||||
@ -247,6 +257,8 @@ impl<'c> CompatSessionRepository for PgCompatSessionRepository<'c> {
|
|||||||
, created_at
|
, created_at
|
||||||
, finished_at
|
, finished_at
|
||||||
, is_synapse_admin
|
, is_synapse_admin
|
||||||
|
, last_active_at
|
||||||
|
, last_active_ip as "last_active_ip: IpAddr"
|
||||||
FROM compat_sessions
|
FROM compat_sessions
|
||||||
WHERE user_id = $1
|
WHERE user_id = $1
|
||||||
AND device_id = $2
|
AND device_id = $2
|
||||||
@ -309,6 +321,8 @@ impl<'c> CompatSessionRepository for PgCompatSessionRepository<'c> {
|
|||||||
device,
|
device,
|
||||||
created_at,
|
created_at,
|
||||||
is_synapse_admin,
|
is_synapse_admin,
|
||||||
|
last_active_at: None,
|
||||||
|
last_active_ip: None,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -390,6 +404,14 @@ impl<'c> CompatSessionRepository for PgCompatSessionRepository<'c> {
|
|||||||
Expr::col((CompatSessions::Table, CompatSessions::IsSynapseAdmin)),
|
Expr::col((CompatSessions::Table, CompatSessions::IsSynapseAdmin)),
|
||||||
CompatSessionAndSsoLoginLookupIden::IsSynapseAdmin,
|
CompatSessionAndSsoLoginLookupIden::IsSynapseAdmin,
|
||||||
)
|
)
|
||||||
|
.expr_as(
|
||||||
|
Expr::col((CompatSessions::Table, CompatSessions::LastActiveAt)),
|
||||||
|
CompatSessionAndSsoLoginLookupIden::LastActiveAt,
|
||||||
|
)
|
||||||
|
.expr_as(
|
||||||
|
Expr::col((CompatSessions::Table, CompatSessions::LastActiveIp)),
|
||||||
|
CompatSessionAndSsoLoginLookupIden::LastActiveIp,
|
||||||
|
)
|
||||||
.expr_as(
|
.expr_as(
|
||||||
Expr::col((CompatSsoLogins::Table, CompatSsoLogins::CompatSsoLoginId)),
|
Expr::col((CompatSsoLogins::Table, CompatSsoLogins::CompatSsoLoginId)),
|
||||||
CompatSessionAndSsoLoginLookupIden::CompatSsoLoginId,
|
CompatSessionAndSsoLoginLookupIden::CompatSsoLoginId,
|
||||||
|
@ -22,6 +22,8 @@ pub enum UserSessions {
|
|||||||
CreatedAt,
|
CreatedAt,
|
||||||
FinishedAt,
|
FinishedAt,
|
||||||
UserAgent,
|
UserAgent,
|
||||||
|
LastActiveAt,
|
||||||
|
LastActiveIp,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(sea_query::Iden)]
|
#[derive(sea_query::Iden)]
|
||||||
@ -53,6 +55,8 @@ pub enum CompatSessions {
|
|||||||
CreatedAt,
|
CreatedAt,
|
||||||
FinishedAt,
|
FinishedAt,
|
||||||
IsSynapseAdmin,
|
IsSynapseAdmin,
|
||||||
|
LastActiveAt,
|
||||||
|
LastActiveIp,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(sea_query::Iden)]
|
#[derive(sea_query::Iden)]
|
||||||
@ -80,6 +84,8 @@ pub enum OAuth2Sessions {
|
|||||||
ScopeList,
|
ScopeList,
|
||||||
CreatedAt,
|
CreatedAt,
|
||||||
FinishedAt,
|
FinishedAt,
|
||||||
|
LastActiveAt,
|
||||||
|
LastActiveIp,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(sea_query::Iden)]
|
#[derive(sea_query::Iden)]
|
||||||
|
@ -59,6 +59,8 @@ struct OAuthSessionLookup {
|
|||||||
scope_list: Vec<String>,
|
scope_list: Vec<String>,
|
||||||
created_at: DateTime<Utc>,
|
created_at: DateTime<Utc>,
|
||||||
finished_at: Option<DateTime<Utc>>,
|
finished_at: Option<DateTime<Utc>>,
|
||||||
|
last_active_at: Option<DateTime<Utc>>,
|
||||||
|
last_active_ip: Option<IpAddr>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl TryFrom<OAuthSessionLookup> for Session {
|
impl TryFrom<OAuthSessionLookup> for Session {
|
||||||
@ -91,6 +93,8 @@ impl TryFrom<OAuthSessionLookup> for Session {
|
|||||||
user_id: value.user_id.map(Ulid::from),
|
user_id: value.user_id.map(Ulid::from),
|
||||||
user_session_id: value.user_session_id.map(Ulid::from),
|
user_session_id: value.user_session_id.map(Ulid::from),
|
||||||
scope,
|
scope,
|
||||||
|
last_active_at: value.last_active_at,
|
||||||
|
last_active_ip: value.last_active_ip,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -119,6 +123,8 @@ impl<'c> OAuth2SessionRepository for PgOAuth2SessionRepository<'c> {
|
|||||||
, scope_list
|
, scope_list
|
||||||
, created_at
|
, created_at
|
||||||
, finished_at
|
, finished_at
|
||||||
|
, last_active_at
|
||||||
|
, last_active_ip as "last_active_ip: IpAddr"
|
||||||
FROM oauth2_sessions
|
FROM oauth2_sessions
|
||||||
|
|
||||||
WHERE oauth2_session_id = $1
|
WHERE oauth2_session_id = $1
|
||||||
@ -191,6 +197,8 @@ impl<'c> OAuth2SessionRepository for PgOAuth2SessionRepository<'c> {
|
|||||||
user_session_id: user_session.map(|s| s.id),
|
user_session_id: user_session.map(|s| s.id),
|
||||||
client_id: client.id,
|
client_id: client.id,
|
||||||
scope,
|
scope,
|
||||||
|
last_active_at: None,
|
||||||
|
last_active_ip: None,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -273,6 +281,14 @@ impl<'c> OAuth2SessionRepository for PgOAuth2SessionRepository<'c> {
|
|||||||
Expr::col((OAuth2Sessions::Table, OAuth2Sessions::FinishedAt)),
|
Expr::col((OAuth2Sessions::Table, OAuth2Sessions::FinishedAt)),
|
||||||
OAuthSessionLookupIden::FinishedAt,
|
OAuthSessionLookupIden::FinishedAt,
|
||||||
)
|
)
|
||||||
|
.expr_as(
|
||||||
|
Expr::col((OAuth2Sessions::Table, OAuth2Sessions::LastActiveAt)),
|
||||||
|
OAuthSessionLookupIden::LastActiveAt,
|
||||||
|
)
|
||||||
|
.expr_as(
|
||||||
|
Expr::col((OAuth2Sessions::Table, OAuth2Sessions::LastActiveIp)),
|
||||||
|
OAuthSessionLookupIden::LastActiveIp,
|
||||||
|
)
|
||||||
.from(OAuth2Sessions::Table)
|
.from(OAuth2Sessions::Table)
|
||||||
.and_where_option(filter.user().map(|user| {
|
.and_where_option(filter.user().map(|user| {
|
||||||
Expr::col((OAuth2Sessions::Table, OAuth2Sessions::UserId)).eq(Uuid::from(user.id))
|
Expr::col((OAuth2Sessions::Table, OAuth2Sessions::UserId)).eq(Uuid::from(user.id))
|
||||||
|
@ -56,6 +56,8 @@ struct SessionLookup {
|
|||||||
user_session_created_at: DateTime<Utc>,
|
user_session_created_at: DateTime<Utc>,
|
||||||
user_session_finished_at: Option<DateTime<Utc>>,
|
user_session_finished_at: Option<DateTime<Utc>>,
|
||||||
user_session_user_agent: Option<String>,
|
user_session_user_agent: Option<String>,
|
||||||
|
user_session_last_active_at: Option<DateTime<Utc>>,
|
||||||
|
user_session_last_active_ip: Option<IpAddr>,
|
||||||
user_id: Uuid,
|
user_id: Uuid,
|
||||||
user_username: String,
|
user_username: String,
|
||||||
user_primary_user_email_id: Option<Uuid>,
|
user_primary_user_email_id: Option<Uuid>,
|
||||||
@ -83,6 +85,8 @@ impl TryFrom<SessionLookup> for BrowserSession {
|
|||||||
created_at: value.user_session_created_at,
|
created_at: value.user_session_created_at,
|
||||||
finished_at: value.user_session_finished_at,
|
finished_at: value.user_session_finished_at,
|
||||||
user_agent: value.user_session_user_agent,
|
user_agent: value.user_session_user_agent,
|
||||||
|
last_active_at: value.user_session_last_active_at,
|
||||||
|
last_active_ip: value.user_session_last_active_ip,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -144,6 +148,8 @@ impl<'c> BrowserSessionRepository for PgBrowserSessionRepository<'c> {
|
|||||||
, s.created_at AS "user_session_created_at"
|
, s.created_at AS "user_session_created_at"
|
||||||
, s.finished_at AS "user_session_finished_at"
|
, s.finished_at AS "user_session_finished_at"
|
||||||
, s.user_agent AS "user_session_user_agent"
|
, s.user_agent AS "user_session_user_agent"
|
||||||
|
, s.last_active_at AS "user_session_last_active_at"
|
||||||
|
, s.last_active_ip AS "user_session_last_active_ip: IpAddr"
|
||||||
, u.user_id
|
, u.user_id
|
||||||
, u.username AS "user_username"
|
, u.username AS "user_username"
|
||||||
, u.primary_user_email_id AS "user_primary_user_email_id"
|
, u.primary_user_email_id AS "user_primary_user_email_id"
|
||||||
@ -207,6 +213,8 @@ impl<'c> BrowserSessionRepository for PgBrowserSessionRepository<'c> {
|
|||||||
created_at,
|
created_at,
|
||||||
finished_at: None,
|
finished_at: None,
|
||||||
user_agent,
|
user_agent,
|
||||||
|
last_active_at: None,
|
||||||
|
last_active_ip: None,
|
||||||
};
|
};
|
||||||
|
|
||||||
Ok(session)
|
Ok(session)
|
||||||
@ -277,6 +285,14 @@ impl<'c> BrowserSessionRepository for PgBrowserSessionRepository<'c> {
|
|||||||
Expr::col((UserSessions::Table, UserSessions::UserAgent)),
|
Expr::col((UserSessions::Table, UserSessions::UserAgent)),
|
||||||
SessionLookupIden::UserSessionUserAgent,
|
SessionLookupIden::UserSessionUserAgent,
|
||||||
)
|
)
|
||||||
|
.expr_as(
|
||||||
|
Expr::col((UserSessions::Table, UserSessions::LastActiveAt)),
|
||||||
|
SessionLookupIden::UserSessionLastActiveAt,
|
||||||
|
)
|
||||||
|
.expr_as(
|
||||||
|
Expr::col((UserSessions::Table, UserSessions::LastActiveIp)),
|
||||||
|
SessionLookupIden::UserSessionLastActiveIp,
|
||||||
|
)
|
||||||
.expr_as(
|
.expr_as(
|
||||||
Expr::col((Users::Table, Users::UserId)),
|
Expr::col((Users::Table, Users::UserId)),
|
||||||
SessionLookupIden::UserId,
|
SessionLookupIden::UserId,
|
||||||
|
@ -157,6 +157,14 @@ type BrowserSession implements Node & CreationEvent {
|
|||||||
The user-agent string with which the session was created.
|
The user-agent string with which the session was created.
|
||||||
"""
|
"""
|
||||||
userAgent: String
|
userAgent: String
|
||||||
|
"""
|
||||||
|
The last IP address used by the session.
|
||||||
|
"""
|
||||||
|
lastActiveIp: String
|
||||||
|
"""
|
||||||
|
The last time the session was active.
|
||||||
|
"""
|
||||||
|
lastActiveAt: DateTime
|
||||||
}
|
}
|
||||||
|
|
||||||
type BrowserSessionConnection {
|
type BrowserSessionConnection {
|
||||||
@ -239,6 +247,14 @@ type CompatSession implements Node & CreationEvent {
|
|||||||
The state of the session.
|
The state of the session.
|
||||||
"""
|
"""
|
||||||
state: CompatSessionState!
|
state: CompatSessionState!
|
||||||
|
"""
|
||||||
|
The last IP address used by the session.
|
||||||
|
"""
|
||||||
|
lastActiveIp: String
|
||||||
|
"""
|
||||||
|
The last time the session was active.
|
||||||
|
"""
|
||||||
|
lastActiveAt: DateTime
|
||||||
}
|
}
|
||||||
|
|
||||||
type CompatSessionConnection {
|
type CompatSessionConnection {
|
||||||
@ -740,6 +756,14 @@ type Oauth2Session implements Node & CreationEvent {
|
|||||||
User authorized for this session.
|
User authorized for this session.
|
||||||
"""
|
"""
|
||||||
user: User
|
user: User
|
||||||
|
"""
|
||||||
|
The last IP address used by the session.
|
||||||
|
"""
|
||||||
|
lastActiveIp: String
|
||||||
|
"""
|
||||||
|
The last time the session was active.
|
||||||
|
"""
|
||||||
|
lastActiveAt: DateTime
|
||||||
}
|
}
|
||||||
|
|
||||||
type Oauth2SessionConnection {
|
type Oauth2SessionConnection {
|
||||||
|
@ -127,6 +127,10 @@ export type BrowserSession = CreationEvent &
|
|||||||
finishedAt?: Maybe<Scalars["DateTime"]["output"]>;
|
finishedAt?: Maybe<Scalars["DateTime"]["output"]>;
|
||||||
/** ID of the object. */
|
/** ID of the object. */
|
||||||
id: Scalars["ID"]["output"];
|
id: Scalars["ID"]["output"];
|
||||||
|
/** The last time the session was active. */
|
||||||
|
lastActiveAt?: Maybe<Scalars["DateTime"]["output"]>;
|
||||||
|
/** The last IP address used by the session. */
|
||||||
|
lastActiveIp?: Maybe<Scalars["String"]["output"]>;
|
||||||
/** The most recent authentication of this session. */
|
/** The most recent authentication of this session. */
|
||||||
lastAuthentication?: Maybe<Authentication>;
|
lastAuthentication?: Maybe<Authentication>;
|
||||||
/** The state of the session. */
|
/** The state of the session. */
|
||||||
@ -181,6 +185,10 @@ export type CompatSession = CreationEvent &
|
|||||||
finishedAt?: Maybe<Scalars["DateTime"]["output"]>;
|
finishedAt?: Maybe<Scalars["DateTime"]["output"]>;
|
||||||
/** ID of the object. */
|
/** ID of the object. */
|
||||||
id: Scalars["ID"]["output"];
|
id: Scalars["ID"]["output"];
|
||||||
|
/** The last time the session was active. */
|
||||||
|
lastActiveAt?: Maybe<Scalars["DateTime"]["output"]>;
|
||||||
|
/** The last IP address used by the session. */
|
||||||
|
lastActiveIp?: Maybe<Scalars["String"]["output"]>;
|
||||||
/** The associated SSO login, if any. */
|
/** The associated SSO login, if any. */
|
||||||
ssoLogin?: Maybe<CompatSsoLogin>;
|
ssoLogin?: Maybe<CompatSsoLogin>;
|
||||||
/** The state of the session. */
|
/** The state of the session. */
|
||||||
@ -544,6 +552,10 @@ export type Oauth2Session = CreationEvent &
|
|||||||
finishedAt?: Maybe<Scalars["DateTime"]["output"]>;
|
finishedAt?: Maybe<Scalars["DateTime"]["output"]>;
|
||||||
/** ID of the object. */
|
/** ID of the object. */
|
||||||
id: Scalars["ID"]["output"];
|
id: Scalars["ID"]["output"];
|
||||||
|
/** The last time the session was active. */
|
||||||
|
lastActiveAt?: Maybe<Scalars["DateTime"]["output"]>;
|
||||||
|
/** The last IP address used by the session. */
|
||||||
|
lastActiveIp?: Maybe<Scalars["String"]["output"]>;
|
||||||
/** Scope granted for this session. */
|
/** Scope granted for this session. */
|
||||||
scope: Scalars["String"]["output"];
|
scope: Scalars["String"]["output"];
|
||||||
/** The state of the session. */
|
/** The state of the session. */
|
||||||
|
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user