const grpc = require('@grpc/grpc-js'); const protoLoader = require('@grpc/proto-loader'); const path = require('path'); const bcrypt = require('bcrypt'); const PROTO_PATH = path.resolve('./protos/auth.proto'); const packageDefinition = protoLoader.loadSync(PROTO_PATH, { keepCase: true, longs: String, enum: String, defaults: true, oneofs: true }); const authProto = grpc.loadPackageDefinition(packageDefinition); module.exports = { name: 'auth', dependencies: ["database"], // Ensure 'database' service is loaded before 'auth' actions: { async login(ctx) { return new Promise((resolve, reject) => { const client = new authProto.AuthService('localhost:50051', grpc.credentials.createInsecure()); client.login({ email: ctx.params.email, password: ctx.params.password }, (error, response) => { if (error) { reject(error); } else { resolve(response); } }); }); }, async register(ctx) { return new Promise((resolve, reject) => { const client = new authProto.AuthService('localhost:50051', grpc.credentials.createInsecure()); client.register({ email: ctx.params.email, password: ctx.params.password }, (error, response) => { if (error) { reject(error); } else { resolve(response); } }); }); }, }, methods: { async userExists(email) { return this.broker.call('database.emailExists', { email }); }, async createUser(email, hashedPassword) { return this.broker.call('database.createUser', { email, password_hash: hashedPassword }); }, async hashPassword(password) { const salt = await bcrypt.genSalt(10); return bcrypt.hash(password, salt); } }, started() { const server = new grpc.Server(); console.log(this.broker) server.addService(authProto.AuthService.service, { Login: async (call, callback) => { const { email, password } = call.request; try { const user = await this.broker.call('database.findUser', { email }); if (user && await bcrypt.compare(password, user.password_hash)) { callback(null, { success: true, message: 'Login successfully' }); } else { callback(null, { success: false, message: 'Invalid Credentials' }); } } catch (error) { callback(null, { success: false, message: 'Internal server error' }); } }, Register: async (call, callback) => { const { email, password } = call.request; try { const userExists = await this.methods.userExists(email); if (userExists) { callback(null, { success: false, message: 'Email already registered' }); return; } const hashedPassword = await this.methods.hashPassword(password); await this.methods.createUser(email, hashedPassword); callback(null, { success: true, message: 'User registered successfully. Please check your email to confirm.' }); } catch (error) { console.error(error); callback(null, { success: false, message: 'Registration failed', error: error.message }); } } }); server.bindAsync('0.0.0.0:50051', grpc.ServerCredentials.createInsecure(), () => { console.log('gRPC Server started on port 50051'); }); } };