71 lines
2.1 KiB
TypeScript
71 lines
2.1 KiB
TypeScript
import { BadRequestException, Inject, Injectable } from '@nestjs/common';
|
|
import { ConfigService } from '@nestjs/config';
|
|
import { Environment } from '../config/env.validation';
|
|
import { PrismaService } from '../prisma/prisma.service';
|
|
import { TbankClient } from './tbank.client';
|
|
import { TbankCrypto } from './tbank.crypto';
|
|
import { PortfolioService } from './portfolio.service';
|
|
|
|
type TbankTokenValidator = Pick<TbankClient, 'validateToken'>;
|
|
|
|
@Injectable()
|
|
export class TbankConnectionService {
|
|
private readonly crypto: TbankCrypto;
|
|
|
|
constructor(
|
|
private readonly prisma: PrismaService,
|
|
config: ConfigService<Environment, true>,
|
|
@Inject(TbankClient) private readonly tbank: TbankTokenValidator,
|
|
private readonly portfolio: PortfolioService,
|
|
) {
|
|
this.crypto = TbankCrypto.fromBase64(
|
|
config.getOrThrow('TOKEN_ENCRYPTION_KEY'),
|
|
);
|
|
}
|
|
|
|
async status(userId: string) {
|
|
const connection = await this.prisma.tbankConnection.findUnique({
|
|
where: { userId },
|
|
});
|
|
return {
|
|
connected: Boolean(connection),
|
|
connectedAt: connection?.connectedAt.toISOString() ?? null,
|
|
};
|
|
}
|
|
|
|
async put(userId: string, value: string) {
|
|
const token = value.trim();
|
|
if (!token) throw new BadRequestException({ code: 'VALIDATION_ERROR' });
|
|
try {
|
|
await this.tbank.validateToken(token);
|
|
} catch (error) {
|
|
if (error instanceof Error && error.message === 'INVALID_TBANK_TOKEN') {
|
|
throw new BadRequestException({ code: 'INVALID_TBANK_TOKEN' });
|
|
}
|
|
throw error;
|
|
}
|
|
const connection = await this.prisma.tbankConnection.upsert({
|
|
where: { userId },
|
|
create: {
|
|
userId,
|
|
encryptedToken: this.crypto.encrypt(token),
|
|
connectedAt: new Date(),
|
|
},
|
|
update: {
|
|
encryptedToken: this.crypto.encrypt(token),
|
|
connectedAt: new Date(),
|
|
},
|
|
});
|
|
this.portfolio.invalidate(userId);
|
|
return {
|
|
connected: true,
|
|
connectedAt: connection.connectedAt.toISOString(),
|
|
};
|
|
}
|
|
|
|
async delete(userId: string): Promise<void> {
|
|
await this.prisma.tbankConnection.deleteMany({ where: { userId } });
|
|
this.portfolio.invalidate(userId);
|
|
}
|
|
}
|