mirror of
https://github.com/immich-app/immich.git
synced 2026-03-01 18:19:10 +03:00
feat: lock auth session (#18322)
This commit is contained in:
@@ -306,6 +306,25 @@ class NotificationAccess {
|
||||
}
|
||||
}
|
||||
|
||||
class SessionAccess {
|
||||
constructor(private db: Kysely<DB>) {}
|
||||
|
||||
@GenerateSql({ params: [DummyValue.UUID, DummyValue.UUID_SET] })
|
||||
@ChunkedSet({ paramIndex: 1 })
|
||||
async checkOwnerAccess(userId: string, sessionIds: Set<string>) {
|
||||
if (sessionIds.size === 0) {
|
||||
return new Set<string>();
|
||||
}
|
||||
|
||||
return this.db
|
||||
.selectFrom('sessions')
|
||||
.select('sessions.id')
|
||||
.where('sessions.id', 'in', [...sessionIds])
|
||||
.where('sessions.userId', '=', userId)
|
||||
.execute()
|
||||
.then((sessions) => new Set(sessions.map((session) => session.id)));
|
||||
}
|
||||
}
|
||||
class StackAccess {
|
||||
constructor(private db: Kysely<DB>) {}
|
||||
|
||||
@@ -456,6 +475,7 @@ export class AccessRepository {
|
||||
notification: NotificationAccess;
|
||||
person: PersonAccess;
|
||||
partner: PartnerAccess;
|
||||
session: SessionAccess;
|
||||
stack: StackAccess;
|
||||
tag: TagAccess;
|
||||
timeline: TimelineAccess;
|
||||
@@ -469,6 +489,7 @@ export class AccessRepository {
|
||||
this.notification = new NotificationAccess(db);
|
||||
this.person = new PersonAccess(db);
|
||||
this.partner = new PartnerAccess(db);
|
||||
this.session = new SessionAccess(db);
|
||||
this.stack = new StackAccess(db);
|
||||
this.tag = new TagAccess(db);
|
||||
this.timeline = new TimelineAccess(db);
|
||||
|
||||
@@ -20,20 +20,20 @@ export class SessionRepository {
|
||||
.where((eb) =>
|
||||
eb.or([
|
||||
eb('updatedAt', '<=', DateTime.now().minus({ days: 90 }).toJSDate()),
|
||||
eb.and([eb('expiredAt', 'is not', null), eb('expiredAt', '<=', DateTime.now().toJSDate())]),
|
||||
eb.and([eb('expiresAt', 'is not', null), eb('expiresAt', '<=', DateTime.now().toJSDate())]),
|
||||
]),
|
||||
)
|
||||
.returning(['id', 'deviceOS', 'deviceType'])
|
||||
.execute();
|
||||
}
|
||||
|
||||
@GenerateSql({ params: [{ updatedBefore: DummyValue.DATE }] })
|
||||
search(options: SessionSearchOptions) {
|
||||
@GenerateSql({ params: [DummyValue.UUID] })
|
||||
get(id: string) {
|
||||
return this.db
|
||||
.selectFrom('sessions')
|
||||
.selectAll()
|
||||
.where('sessions.updatedAt', '<=', options.updatedBefore)
|
||||
.execute();
|
||||
.select(['id', 'expiresAt', 'pinExpiresAt'])
|
||||
.where('id', '=', id)
|
||||
.executeTakeFirst();
|
||||
}
|
||||
|
||||
@GenerateSql({ params: [DummyValue.STRING] })
|
||||
@@ -52,7 +52,7 @@ export class SessionRepository {
|
||||
])
|
||||
.where('sessions.token', '=', token)
|
||||
.where((eb) =>
|
||||
eb.or([eb('sessions.expiredAt', 'is', null), eb('sessions.expiredAt', '>', DateTime.now().toJSDate())]),
|
||||
eb.or([eb('sessions.expiresAt', 'is', null), eb('sessions.expiresAt', '>', DateTime.now().toJSDate())]),
|
||||
)
|
||||
.executeTakeFirst();
|
||||
}
|
||||
@@ -64,6 +64,9 @@ export class SessionRepository {
|
||||
.innerJoin('users', (join) => join.onRef('users.id', '=', 'sessions.userId').on('users.deletedAt', 'is', null))
|
||||
.selectAll('sessions')
|
||||
.where('sessions.userId', '=', userId)
|
||||
.where((eb) =>
|
||||
eb.or([eb('sessions.expiresAt', 'is', null), eb('sessions.expiresAt', '>', DateTime.now().toJSDate())]),
|
||||
)
|
||||
.orderBy('sessions.updatedAt', 'desc')
|
||||
.orderBy('sessions.createdAt', 'desc')
|
||||
.execute();
|
||||
@@ -86,4 +89,9 @@ export class SessionRepository {
|
||||
async delete(id: string) {
|
||||
await this.db.deleteFrom('sessions').where('id', '=', asUuid(id)).execute();
|
||||
}
|
||||
|
||||
@GenerateSql({ params: [DummyValue.UUID] })
|
||||
async lockAll(userId: string) {
|
||||
await this.db.updateTable('sessions').set({ pinExpiresAt: null }).where('userId', '=', userId).execute();
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user