feat: enhance authentication and user management with token-based system
- Implemented robust token-based authentication with access and refresh tokens - Added JWT token generation, verification, and rotation mechanisms - Created services for token management, Memcached, and MinIO storage - Enhanced user registration and login with device-specific tokens - Added support for profile picture upload and management via MinIO - Implemented secure password hashing with crypto - Updated Prisma schema to support refresh tokens and profile picture storage - Added GraphQL mutations for logout, token refresh, and profile picture handling - Integrated environment configuration with Zod validation - Improved error handling and authentication middleware
This commit is contained in:
parent
d4d99fb5e7
commit
d29d116214
22 changed files with 1992 additions and 388 deletions
106
apps/api/src/services/minio.service.ts
Normal file
106
apps/api/src/services/minio.service.ts
Normal file
|
@ -0,0 +1,106 @@
|
|||
import { Client } from 'minio';
|
||||
import { MinioConfig } from '../config';
|
||||
|
||||
/**
|
||||
* Service for handling MinIO operations
|
||||
*/
|
||||
export class MinioService {
|
||||
private client: Client;
|
||||
private bucketName: string;
|
||||
private readonly defaultExpiry = 60 * 60; // 1 hour in seconds
|
||||
private initialized = false;
|
||||
/**
|
||||
* Creates a new MinioService instance
|
||||
* @param config - MinIO configuration
|
||||
*/
|
||||
constructor(config: MinioConfig) {
|
||||
this.client = new Client(config);
|
||||
this.bucketName = config.bucketName;
|
||||
}
|
||||
|
||||
/**
|
||||
* Initializes the MinIO service by ensuring the bucket exists
|
||||
*/
|
||||
public async initialize(): Promise<void> {
|
||||
if (this.initialized) {
|
||||
return;
|
||||
}
|
||||
const bucketExists = await this.client.bucketExists(this.bucketName);
|
||||
if (!bucketExists) {
|
||||
await this.client.makeBucket(this.bucketName, 'us-east-1');
|
||||
// Set the bucket policy to allow public read access
|
||||
const policy = {
|
||||
Version: '2012-10-17',
|
||||
Statement: [
|
||||
{
|
||||
Effect: 'Allow',
|
||||
Principal: { AWS: ['*'] },
|
||||
Action: ['s3:GetObject'],
|
||||
Resource: [`arn:aws:s3:::${this.bucketName}/*`],
|
||||
},
|
||||
],
|
||||
};
|
||||
await this.client.setBucketPolicy(
|
||||
this.bucketName,
|
||||
JSON.stringify(policy)
|
||||
);
|
||||
}
|
||||
this.initialized = true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Generates a presigned URL for uploading a file
|
||||
* @param objectName - Name of the object to upload
|
||||
* @param expiryInSeconds - Expiry time in seconds (default: 1 hour)
|
||||
* @returns Presigned URL for uploading
|
||||
*/
|
||||
public async generateUploadUrl(
|
||||
objectName: string,
|
||||
expiryInSeconds: number = this.defaultExpiry
|
||||
): Promise<string> {
|
||||
return this.client.presignedPutObject(
|
||||
this.bucketName,
|
||||
objectName,
|
||||
expiryInSeconds
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Generates a presigned URL for downloading a file
|
||||
* @param objectName - Name of the object to download
|
||||
* @param expiryInSeconds - Expiry time in seconds (default: 1 hour)
|
||||
* @returns Presigned URL for downloading
|
||||
*/
|
||||
public async generateDownloadUrl(
|
||||
objectName: string,
|
||||
expiryInSeconds: number = this.defaultExpiry
|
||||
): Promise<string> {
|
||||
return this.client.presignedGetObject(
|
||||
this.bucketName,
|
||||
objectName,
|
||||
expiryInSeconds
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if an object exists in the bucket
|
||||
* @param objectName - Name of the object to check
|
||||
* @returns True if the object exists, false otherwise
|
||||
*/
|
||||
public async objectExists(objectName: string): Promise<boolean> {
|
||||
try {
|
||||
await this.client.statObject(this.bucketName, objectName);
|
||||
return true;
|
||||
} catch (error) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Deletes an object from the bucket
|
||||
* @param objectName - Name of the object to delete
|
||||
*/
|
||||
public async deleteObject(objectName: string): Promise<void> {
|
||||
await this.client.removeObject(this.bucketName, objectName);
|
||||
}
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue