Skip to content

Commit 3de6c74

Browse files
hrideshmgtejasai2007
authored andcommitted
fix: remove logout as session tokens are HttpOnly
1 parent 4e47493 commit 3de6c74

File tree

6 files changed

+73
-95
lines changed

6 files changed

+73
-95
lines changed

docs/auth.md

Lines changed: 0 additions & 44 deletions
Original file line numberDiff line numberDiff line change
@@ -140,18 +140,6 @@ curl -X POST http://localhost:5000/ \
140140
}'
141141
```
142142

143-
### Logout
144-
145-
```graphql
146-
mutation {
147-
logout(sessionToken: "your_session_token_here")
148-
}
149-
```
150-
151-
This invalidates the specified session for the current user.
152-
153-
**Returns:** `true` if successful, `false` if not authenticated
154-
155143
## Bot Management
156144
### Creating Bots (Admin Only)
157145

@@ -180,16 +168,6 @@ mutation {
180168

181169
Bots use API keys instead of session tokens. Include the API key in the `Authorization` header in the same format as before.
182170

183-
### Deleting Bots (Admin Only)
184-
185-
```graphql
186-
mutation {
187-
deleteBot(apiKeyId: 1)
188-
}
189-
```
190-
191-
**Returns:** `true` if successful
192-
193171

194172
## Permission Checking in Code
195173

@@ -246,17 +224,6 @@ The GitHub account is not part of the specified organization. Either:
246224

247225
### GraphQL Mutations
248226

249-
#### `logout(sessionToken: String!): Boolean!`
250-
251-
Invalidate the specified session for current user.
252-
253-
**Input:**
254-
- `sessionToken`: The session token to invalidate
255-
256-
**Returns:** `true` if successful, `false` if not authenticated
257-
258-
---
259-
260227
#### `createBot(name: String!): String!` 🔒 Admin only
261228

262229
Create a new bot with API key.
@@ -266,17 +233,6 @@ Create a new bot with API key.
266233

267234
**Returns:** The API key string (only shown once!)
268235

269-
---
270-
271-
#### `deleteBot(apiKeyId: Int!): Boolean!` 🔒 Admin only
272-
273-
Delete a bot and revoke its API key.
274-
275-
**Input:**
276-
- `apiKeyId`: ID of the API key to delete
277-
278-
**Returns:** `true` if successful
279-
280236
## Example
281237

282238
### Complete Member Authentication Flow

src/auth/session.rs

Lines changed: 0 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -73,23 +73,6 @@ impl SessionService {
7373
Ok(result)
7474
}
7575

76-
pub async fn delete_session_by_token(pool: &PgPool, token: &str) -> Result<(), String> {
77-
let token_hash = Self::hash_token(token);
78-
79-
sqlx::query(
80-
r#"
81-
DELETE FROM Sessions
82-
WHERE token_hash = $1
83-
"#,
84-
)
85-
.bind(token_hash)
86-
.execute(pool)
87-
.await
88-
.map_err(|e| format!("Failed to delete session: {}", e))?;
89-
90-
Ok(())
91-
}
92-
9376
pub async fn cleanup_expired_sessions(pool: &PgPool) -> Result<u64, String> {
9477
let now = chrono::Utc::now().with_timezone(&Kolkata);
9578

Lines changed: 0 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
11
use crate::auth::api_key::ApiKeyService;
22
use crate::auth::guards::AdminGuard;
3-
use crate::auth::session::SessionService;
43
use crate::auth::AuthContext;
54
use crate::models::auth::ApiKeyResponse;
65
use async_graphql::{Context, Object, Result};
@@ -12,24 +11,6 @@ pub struct AuthMutations;
1211

1312
#[Object]
1413
impl AuthMutations {
15-
/// Logout - invalidate session
16-
#[graphql(name = "logout")]
17-
async fn logout(&self, ctx: &Context<'_>, session_token: String) -> Result<bool> {
18-
let pool = ctx.data::<Arc<PgPool>>().expect("Pool must be in context.");
19-
let auth = ctx
20-
.data::<AuthContext>()
21-
.expect("AuthContext must be in context.");
22-
23-
if auth.is_authenticated() {
24-
SessionService::delete_session_by_token(pool.as_ref(), &session_token)
25-
.await
26-
.map_err(|e| format!("Failed to logout: {}", e))?;
27-
Ok(true)
28-
} else {
29-
Ok(false)
30-
}
31-
}
32-
3314
/// Create a new bot with API key (Admin only)
3415
#[graphql(name = "createBot", guard = "AdminGuard")]
3516
async fn create_bot(&self, ctx: &Context<'_>, name: String) -> Result<ApiKeyResponse> {
@@ -50,16 +31,4 @@ impl AuthMutations {
5031

5132
Ok(ApiKeyResponse { api_key })
5233
}
53-
54-
/// Delete a bot (Admin only)
55-
#[graphql(name = "deleteBot", guard = "AdminGuard")]
56-
async fn delete_bot(&self, ctx: &Context<'_>, api_key_id: i32) -> Result<bool> {
57-
let pool = ctx.data::<Arc<PgPool>>().expect("Pool must be in context.");
58-
59-
ApiKeyService::delete_api_key(pool.as_ref(), api_key_id)
60-
.await
61-
.map_err(|e| format!("Failed to delete bot: {}", e))?;
62-
63-
Ok(true)
64-
}
6534
}

src/graphql/queries/member_queries.rs

Lines changed: 66 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
use crate::auth::guards::AuthGuard;
22
use crate::auth::AuthContext;
3-
use crate::models::{attendance::AttendanceRecord, status_update::StatusUpdateRecord};
3+
use crate::models::{attendance::Aggregate, attendance::AttendanceRecord, status_update::StatusUpdateRecord,};
44
use async_graphql::{ComplexObject, Context, Object, Result};
55
use chrono::NaiveDate;
66
use sqlx::PgPool;
@@ -19,9 +19,14 @@ pub struct AttendanceInfo {
1919
member_id: i32,
2020
}
2121

22+
pub struct Lab;
23+
2224
#[Object]
2325
impl MemberQueries {
24-
#[graphql(guard = "AuthGuard")]
26+
27+
async fn lab(&self, _ctx: &Context<'_>) -> Lab {
28+
Lab
29+
}
2530
pub async fn all_members(
2631
&self,
2732
ctx: &Context<'_>,
@@ -378,3 +383,62 @@ impl Member {
378383
}
379384
}
380385
}
386+
387+
#[Object]
388+
389+
impl Lab {
390+
pub async fn attendance(
391+
&self,
392+
ctx: &Context<'_>,
393+
start_date: NaiveDate,
394+
end_date: NaiveDate,
395+
) -> Result<Vec<Aggregate>> {
396+
let pool = ctx.data::<Arc<PgPool>>().expect("Pool must be in context.");
397+
398+
// will give the total count
399+
let mut query = sqlx::QueryBuilder::new(
400+
r#"
401+
SELECT
402+
all_dates.date,
403+
p.present_count
404+
FROM (
405+
SELECT
406+
date,
407+
COUNT(*) AS total_count
408+
FROM attendance
409+
WHERE date BETWEEN "#,
410+
);
411+
412+
query.push_bind(start_date);
413+
query.push(" AND ");
414+
query.push_bind(end_date);
415+
query.push(" GROUP BY date ) AS all_dates ");
416+
417+
// sub query of present members joined with the above total countS
418+
query.push(
419+
"LEFT JOIN (
420+
SELECT
421+
date,
422+
COUNT(*) AS present_count
423+
FROM attendance
424+
WHERE is_present = 't'
425+
AND date BETWEEN ",
426+
);
427+
query.push_bind(start_date);
428+
query.push(" AND ");
429+
query.push_bind(end_date);
430+
query.push(
431+
" GROUP BY date
432+
) AS p
433+
ON all_dates.date = p.date
434+
ORDER BY all_dates.date;",
435+
);
436+
437+
let results: Vec<Aggregate> = query
438+
.build_query_as::<Aggregate>()
439+
.fetch_all(pool.as_ref())
440+
.await?;
441+
442+
Ok(results)
443+
}
444+
}

src/main.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -159,7 +159,7 @@ fn setup_cors() -> CorsLayer {
159159
];
160160

161161
CorsLayer::new()
162-
// TODO 2: https://github.com/amfoss/root/issues/151, enabling all origins for the time being
162+
// TODO 2: https://github.com/amfoss/root/issues/151
163163
.allow_credentials(true)
164164
.allow_origin(origins)
165165
.allow_methods([Method::GET, Method::POST, Method::OPTIONS])

src/models/attendance.rs

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,3 +21,9 @@ pub struct MarkAttendanceInput {
2121
pub date: NaiveDate,
2222
pub hmac_signature: String,
2323
}
24+
25+
#[derive(FromRow, SimpleObject)]
26+
pub struct Aggregate {
27+
pub date: NaiveDate,
28+
pub present_count: Option<i64>,
29+
}

0 commit comments

Comments
 (0)