@accounter/server
Version:
Accounter GraphQL server
169 lines • 6.28 kB
JavaScript
import { __decorate, __metadata, __param } from "tslib";
import { ManagementClient } from 'auth0';
import { Inject, Injectable, Scope } from 'graphql-modules';
import { ENVIRONMENT } from '../../../shared/tokens.js';
let Auth0ManagementProvider = class Auth0ManagementProvider {
env;
client;
constructor(env) {
this.env = env;
this.initializeClient();
}
initializeClient() {
if (this.env.auth0) {
this.client = new ManagementClient({
domain: this.env.auth0.domain,
clientId: this.env.auth0.clientId,
clientSecret: this.env.auth0.clientSecret,
audience: this.env.auth0.managementAudience,
});
}
else {
console.warn('Auth0 not configured, Auth0ManagementProvider disabled');
}
}
getClient() {
if (!this.client) {
throw new Error('Auth0 client not initialized');
}
return this.client;
}
async getUserByEmail(email) {
const client = this.getClient();
try {
const users = await client.users.listUsersByEmail({ email });
if (users?.length > 0) {
return users[0].user_id ?? null;
}
return null;
}
catch (error) {
console.error(`Failed to get Auth0 user by email ${email}:`, error);
throw new Error(`Failed to get Auth0 user by email: ${error.message}`, {
cause: error,
});
}
}
async getUserEmailById(auth0UserId) {
const client = this.getClient();
try {
const user = await client.users.get(auth0UserId);
return {
email: typeof user?.email === 'string' ? user.email : null,
emailVerified: user?.email_verified === true,
};
}
catch (error) {
console.error(`Failed to get Auth0 user by id ${auth0UserId}:`, error);
return null;
}
}
async createBlockedUser(email, password) {
const client = this.getClient();
const temporaryPassword = password || this.generateTemporaryPassword();
try {
// Create user with blocked status (prevents login until invitation accepted)
const user = await client.users.create({
connection: 'Username-Password-Authentication',
email,
password: temporaryPassword, // User will reset via invitation
email_verified: false,
blocked: true,
app_metadata: {
registered_by: 'accounter',
},
});
if (!user.user_id) {
throw new Error('Auth0 did not return a user ID');
}
// Returns Auth0 user ID (e.g., "auth0|507f...")
return user.user_id;
}
catch (error) {
console.error('Failed to create Auth0 user:', error);
throw new Error(`Failed to create Auth0 user: ${error.message}`, { cause: error });
}
}
async unblockUser(auth0UserId) {
const client = this.getClient();
try {
await client.users.update(auth0UserId, { blocked: false });
}
catch (error) {
console.error(`Failed to unblock Auth0 user ${auth0UserId}:`, error);
throw new Error(`Failed to unblock Auth0 user: ${error.message}`, {
cause: error,
});
}
}
async blockUser(auth0UserId) {
const client = this.getClient();
try {
await client.users.update(auth0UserId, { blocked: true });
}
catch (error) {
console.error(`Failed to block Auth0 user ${auth0UserId}:`, error);
throw new Error(`Failed to block Auth0 user: ${error.message}`, { cause: error });
}
}
async deleteUser(auth0UserId) {
const client = this.getClient();
try {
// Cleanup for expired invitations
await client.users.delete(auth0UserId);
}
catch (error) {
console.error(`Failed to delete Auth0 user ${auth0UserId}:`, error);
throw new Error(`Failed to delete Auth0 user: ${error.message}`, { cause: error });
}
}
async sendPasswordResetEmail(auth0UserId) {
const client = this.getClient();
try {
const { ticket } = await client.tickets.changePassword({
user_id: auth0UserId,
mark_email_as_verified: true, // Mark verified only after password change
result_url: this.env.general.frontendUrl
? `${this.env.general.frontendUrl}/login`
: undefined,
});
return ticket;
}
catch (error) {
console.error('Failed to trigger password change', error);
throw new Error(`Failed to trigger password change: ${error.message}`, {
cause: error,
});
}
}
generateTemporaryPassword() {
// Generate a random password that meets strict Auth0 requirements:
// 8+ chars, lower, upper, number, special char
const lower = 'abcdefghijklmnopqrstuvwxyz';
const upper = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ';
const numbers = '0123456789';
const special = '!@#$%^&*()_+~`|}{[]\\:;?><,./-=';
const all = lower + upper + numbers + special;
const pick = (str) => {
const randomValues = new Uint32Array(1);
globalThis.crypto.getRandomValues(randomValues);
return str[randomValues[0] % str.length];
};
const password = pick(lower) +
pick(upper) +
pick(numbers) +
pick(special) +
Array.from({ length: 12 }, () => pick(all)).join('');
return password;
}
};
Auth0ManagementProvider = __decorate([
Injectable({
scope: Scope.Singleton,
global: true,
}),
__param(0, Inject(ENVIRONMENT)),
__metadata("design:paramtypes", [Object])
], Auth0ManagementProvider);
export { Auth0ManagementProvider };
//# sourceMappingURL=auth0-management.provider.js.map