mirror of
https://github.com/immich-app/immich
synced 2025-11-07 17:27:20 +00:00
feat(web,server): manage authorized devices (#2329)
* feat: manage authorized devices * chore: open api * get header from mobile app * write header from mobile app * styling * fix unit test * feat: use relative time * feat: update access time * fix: tests * chore: confirm wording * chore: bump test coverage thresholds * feat: add some icons * chore: icon tweaks --------- Co-authored-by: Alex Tran <alex.tran1502@gmail.com>
This commit is contained in:
parent
aa91b946fa
commit
b8313abfa8
41 changed files with 1209 additions and 93 deletions
|
|
@ -1,5 +1,7 @@
|
|||
import { UserEntity } from '@app/infra/entities';
|
||||
import { UserEntity, UserTokenEntity } from '@app/infra/entities';
|
||||
import { Injectable, UnauthorizedException } from '@nestjs/common';
|
||||
import { DateTime } from 'luxon';
|
||||
import { LoginDetails } from '../auth';
|
||||
import { ICryptoRepository } from '../crypto';
|
||||
import { IUserTokenRepository } from './user-token.repository';
|
||||
|
||||
|
|
@ -9,9 +11,16 @@ export class UserTokenCore {
|
|||
|
||||
async validate(tokenValue: string) {
|
||||
const hashedToken = this.crypto.hashSha256(tokenValue);
|
||||
const token = await this.repository.get(hashedToken);
|
||||
let token = await this.repository.getByToken(hashedToken);
|
||||
|
||||
if (token?.user) {
|
||||
const now = DateTime.now();
|
||||
const updatedAt = DateTime.fromJSDate(token.updatedAt);
|
||||
const diff = now.diff(updatedAt, ['hours']);
|
||||
if (diff.hours > 1) {
|
||||
token = await this.repository.save({ ...token, updatedAt: new Date() });
|
||||
}
|
||||
|
||||
return {
|
||||
...token.user,
|
||||
isPublicUser: false,
|
||||
|
|
@ -25,18 +34,24 @@ export class UserTokenCore {
|
|||
throw new UnauthorizedException('Invalid user token');
|
||||
}
|
||||
|
||||
public async createToken(user: UserEntity): Promise<string> {
|
||||
async create(user: UserEntity, loginDetails: LoginDetails): Promise<string> {
|
||||
const key = this.crypto.randomBytes(32).toString('base64').replace(/\W/g, '');
|
||||
const token = this.crypto.hashSha256(key);
|
||||
await this.repository.create({
|
||||
token,
|
||||
user,
|
||||
deviceOS: loginDetails.deviceOS,
|
||||
deviceType: loginDetails.deviceType,
|
||||
});
|
||||
|
||||
return key;
|
||||
}
|
||||
|
||||
public async deleteToken(id: string): Promise<void> {
|
||||
await this.repository.delete(id);
|
||||
async delete(userId: string, id: string): Promise<void> {
|
||||
await this.repository.delete(userId, id);
|
||||
}
|
||||
|
||||
getAll(userId: string): Promise<UserTokenEntity[]> {
|
||||
return this.repository.getAll(userId);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue