mirror of
https://dev.azure.com/globalhealthx/EMR/_git/helix-engage-server
synced 2026-04-12 02:18:18 +00:00
lint and format
This commit is contained in:
@@ -5,28 +5,32 @@ import { OzonetelAgentService } from '../ozonetel/ozonetel-agent.service';
|
||||
|
||||
@Controller('auth')
|
||||
export class AuthController {
|
||||
private readonly logger = new Logger(AuthController.name);
|
||||
private readonly graphqlUrl: string;
|
||||
private readonly workspaceSubdomain: string;
|
||||
private readonly origin: string;
|
||||
private readonly logger = new Logger(AuthController.name);
|
||||
private readonly graphqlUrl: string;
|
||||
private readonly workspaceSubdomain: string;
|
||||
private readonly origin: string;
|
||||
|
||||
constructor(
|
||||
private config: ConfigService,
|
||||
private ozonetelAgent: OzonetelAgentService,
|
||||
) {
|
||||
this.graphqlUrl = config.get<string>('platform.graphqlUrl')!;
|
||||
this.workspaceSubdomain = process.env.PLATFORM_WORKSPACE_SUBDOMAIN ?? 'fortytwo-dev';
|
||||
this.origin = process.env.PLATFORM_ORIGIN ?? 'http://fortytwo-dev.localhost:4010';
|
||||
}
|
||||
constructor(
|
||||
private config: ConfigService,
|
||||
private ozonetelAgent: OzonetelAgentService,
|
||||
) {
|
||||
this.graphqlUrl = config.get<string>('platform.graphqlUrl')!;
|
||||
this.workspaceSubdomain =
|
||||
process.env.PLATFORM_WORKSPACE_SUBDOMAIN ?? 'fortytwo-dev';
|
||||
this.origin =
|
||||
process.env.PLATFORM_ORIGIN ?? 'http://fortytwo-dev.localhost:4010';
|
||||
}
|
||||
|
||||
@Post('login')
|
||||
async login(@Body() body: { email: string; password: string }) {
|
||||
this.logger.log(`Login attempt for ${body.email}`);
|
||||
@Post('login')
|
||||
async login(@Body() body: { email: string; password: string }) {
|
||||
this.logger.log(`Login attempt for ${body.email}`);
|
||||
|
||||
try {
|
||||
// Step 1: Get login token
|
||||
const loginRes = await axios.post(this.graphqlUrl, {
|
||||
query: `mutation GetLoginToken($email: String!, $password: String!) {
|
||||
try {
|
||||
// Step 1: Get login token
|
||||
const loginRes = await axios.post(
|
||||
this.graphqlUrl,
|
||||
{
|
||||
query: `mutation GetLoginToken($email: String!, $password: String!) {
|
||||
getLoginTokenFromCredentials(
|
||||
email: $email
|
||||
password: $password
|
||||
@@ -35,26 +39,31 @@ export class AuthController {
|
||||
loginToken { token }
|
||||
}
|
||||
}`,
|
||||
variables: { email: body.email, password: body.password },
|
||||
}, {
|
||||
headers: {
|
||||
'Content-Type': 'application/json',
|
||||
'X-Workspace-Subdomain': this.workspaceSubdomain,
|
||||
},
|
||||
});
|
||||
variables: { email: body.email, password: body.password },
|
||||
},
|
||||
{
|
||||
headers: {
|
||||
'Content-Type': 'application/json',
|
||||
'X-Workspace-Subdomain': this.workspaceSubdomain,
|
||||
},
|
||||
},
|
||||
);
|
||||
|
||||
if (loginRes.data.errors) {
|
||||
throw new HttpException(
|
||||
loginRes.data.errors[0]?.message ?? 'Login failed',
|
||||
401,
|
||||
);
|
||||
}
|
||||
if (loginRes.data.errors) {
|
||||
throw new HttpException(
|
||||
loginRes.data.errors[0]?.message ?? 'Login failed',
|
||||
401,
|
||||
);
|
||||
}
|
||||
|
||||
const loginToken = loginRes.data.data.getLoginTokenFromCredentials.loginToken.token;
|
||||
const loginToken =
|
||||
loginRes.data.data.getLoginTokenFromCredentials.loginToken.token;
|
||||
|
||||
// Step 2: Exchange for access + refresh tokens
|
||||
const tokenRes = await axios.post(this.graphqlUrl, {
|
||||
query: `mutation GetAuthTokens($loginToken: String!) {
|
||||
// Step 2: Exchange for access + refresh tokens
|
||||
const tokenRes = await axios.post(
|
||||
this.graphqlUrl,
|
||||
{
|
||||
query: `mutation GetAuthTokens($loginToken: String!) {
|
||||
getAuthTokensFromLoginToken(
|
||||
loginToken: $loginToken
|
||||
origin: "${this.origin}"
|
||||
@@ -65,99 +74,114 @@ export class AuthController {
|
||||
}
|
||||
}
|
||||
}`,
|
||||
variables: { loginToken },
|
||||
}, {
|
||||
headers: {
|
||||
'Content-Type': 'application/json',
|
||||
'X-Workspace-Subdomain': this.workspaceSubdomain,
|
||||
},
|
||||
});
|
||||
variables: { loginToken },
|
||||
},
|
||||
{
|
||||
headers: {
|
||||
'Content-Type': 'application/json',
|
||||
'X-Workspace-Subdomain': this.workspaceSubdomain,
|
||||
},
|
||||
},
|
||||
);
|
||||
|
||||
if (tokenRes.data.errors) {
|
||||
throw new HttpException(
|
||||
tokenRes.data.errors[0]?.message ?? 'Token exchange failed',
|
||||
401,
|
||||
);
|
||||
}
|
||||
if (tokenRes.data.errors) {
|
||||
throw new HttpException(
|
||||
tokenRes.data.errors[0]?.message ?? 'Token exchange failed',
|
||||
401,
|
||||
);
|
||||
}
|
||||
|
||||
const tokens = tokenRes.data.data.getAuthTokensFromLoginToken.tokens;
|
||||
const accessToken = tokens.accessOrWorkspaceAgnosticToken.token;
|
||||
const tokens = tokenRes.data.data.getAuthTokensFromLoginToken.tokens;
|
||||
const accessToken = tokens.accessOrWorkspaceAgnosticToken.token;
|
||||
|
||||
// Step 3: Fetch user profile with roles
|
||||
const profileRes = await axios.post(this.graphqlUrl, {
|
||||
query: `{ currentUser { id email workspaceMember { id name { firstName lastName } userEmail avatarUrl roles { id label } } } }`,
|
||||
}, {
|
||||
headers: {
|
||||
'Content-Type': 'application/json',
|
||||
'Authorization': `Bearer ${accessToken}`,
|
||||
},
|
||||
});
|
||||
// Step 3: Fetch user profile with roles
|
||||
const profileRes = await axios.post(
|
||||
this.graphqlUrl,
|
||||
{
|
||||
query: `{ currentUser { id email workspaceMember { id name { firstName lastName } userEmail avatarUrl roles { id label } } } }`,
|
||||
},
|
||||
{
|
||||
headers: {
|
||||
'Content-Type': 'application/json',
|
||||
Authorization: `Bearer ${accessToken}`,
|
||||
},
|
||||
},
|
||||
);
|
||||
|
||||
const currentUser = profileRes.data?.data?.currentUser;
|
||||
const workspaceMember = currentUser?.workspaceMember;
|
||||
const roles = workspaceMember?.roles ?? [];
|
||||
const roleLabels = roles.map((r: any) => r.label);
|
||||
const currentUser = profileRes.data?.data?.currentUser;
|
||||
const workspaceMember = currentUser?.workspaceMember;
|
||||
const roles = workspaceMember?.roles ?? [];
|
||||
const roleLabels = roles.map((r: any) => r.label);
|
||||
|
||||
// Determine app role from platform roles
|
||||
let appRole = 'executive'; // default
|
||||
if (roleLabels.includes('HelixEngage Manager')) {
|
||||
appRole = 'admin';
|
||||
} else if (roleLabels.includes('HelixEngage User')) {
|
||||
// Distinguish CC agent from executive by email convention or config
|
||||
// For now, emails containing 'cc' map to cc-agent
|
||||
const email = workspaceMember?.userEmail ?? body.email;
|
||||
appRole = email.includes('cc') ? 'cc-agent' : 'executive';
|
||||
}
|
||||
// Determine app role from platform roles
|
||||
let appRole = 'executive'; // default
|
||||
if (roleLabels.includes('HelixEngage Manager')) {
|
||||
appRole = 'admin';
|
||||
} else if (roleLabels.includes('HelixEngage User')) {
|
||||
// Distinguish CC agent from executive by email convention or config
|
||||
// For now, emails containing 'cc' map to cc-agent
|
||||
const email = workspaceMember?.userEmail ?? body.email;
|
||||
appRole = email.includes('cc') ? 'cc-agent' : 'executive';
|
||||
}
|
||||
|
||||
this.logger.log(`User ${body.email} logged in with role: ${appRole} (platform roles: ${roleLabels.join(', ')})`);
|
||||
this.logger.log(
|
||||
`User ${body.email} logged in with role: ${appRole} (platform roles: ${roleLabels.join(', ')})`,
|
||||
);
|
||||
|
||||
// Auto-login Ozonetel agent for CC agents (fire and forget)
|
||||
if (appRole === 'cc-agent') {
|
||||
const ozAgentId = process.env.OZONETEL_AGENT_ID ?? 'agent3';
|
||||
const ozAgentPassword = process.env.OZONETEL_AGENT_PASSWORD ?? 'Test123$';
|
||||
const ozSipId = process.env.OZONETEL_SIP_ID ?? '521814';
|
||||
// Auto-login Ozonetel agent for CC agents (fire and forget)
|
||||
if (appRole === 'cc-agent') {
|
||||
const ozAgentId = process.env.OZONETEL_AGENT_ID ?? 'agent3';
|
||||
const ozAgentPassword =
|
||||
process.env.OZONETEL_AGENT_PASSWORD ?? 'Test123$';
|
||||
const ozSipId = process.env.OZONETEL_SIP_ID ?? '521814';
|
||||
|
||||
this.ozonetelAgent.loginAgent({
|
||||
agentId: ozAgentId,
|
||||
password: ozAgentPassword,
|
||||
phoneNumber: ozSipId,
|
||||
mode: 'blended',
|
||||
}).catch(err => {
|
||||
this.logger.warn(`Ozonetel agent login failed (non-blocking): ${err.message}`);
|
||||
});
|
||||
}
|
||||
this.ozonetelAgent
|
||||
.loginAgent({
|
||||
agentId: ozAgentId,
|
||||
password: ozAgentPassword,
|
||||
phoneNumber: ozSipId,
|
||||
mode: 'blended',
|
||||
})
|
||||
.catch((err) => {
|
||||
this.logger.warn(
|
||||
`Ozonetel agent login failed (non-blocking): ${err.message}`,
|
||||
);
|
||||
});
|
||||
}
|
||||
|
||||
return {
|
||||
accessToken,
|
||||
refreshToken: tokens.refreshToken.token,
|
||||
user: {
|
||||
id: currentUser?.id,
|
||||
email: currentUser?.email,
|
||||
firstName: workspaceMember?.name?.firstName ?? '',
|
||||
lastName: workspaceMember?.name?.lastName ?? '',
|
||||
avatarUrl: workspaceMember?.avatarUrl,
|
||||
role: appRole,
|
||||
platformRoles: roleLabels,
|
||||
},
|
||||
};
|
||||
} catch (error) {
|
||||
if (error instanceof HttpException) throw error;
|
||||
this.logger.error(`Login proxy failed: ${error}`);
|
||||
throw new HttpException('Authentication service unavailable', 503);
|
||||
}
|
||||
return {
|
||||
accessToken,
|
||||
refreshToken: tokens.refreshToken.token,
|
||||
user: {
|
||||
id: currentUser?.id,
|
||||
email: currentUser?.email,
|
||||
firstName: workspaceMember?.name?.firstName ?? '',
|
||||
lastName: workspaceMember?.name?.lastName ?? '',
|
||||
avatarUrl: workspaceMember?.avatarUrl,
|
||||
role: appRole,
|
||||
platformRoles: roleLabels,
|
||||
},
|
||||
};
|
||||
} catch (error) {
|
||||
if (error instanceof HttpException) throw error;
|
||||
this.logger.error(`Login proxy failed: ${error}`);
|
||||
throw new HttpException('Authentication service unavailable', 503);
|
||||
}
|
||||
}
|
||||
|
||||
@Post('refresh')
|
||||
async refresh(@Body() body: { refreshToken: string }) {
|
||||
if (!body.refreshToken) {
|
||||
throw new HttpException('refreshToken required', 400);
|
||||
}
|
||||
|
||||
@Post('refresh')
|
||||
async refresh(@Body() body: { refreshToken: string }) {
|
||||
if (!body.refreshToken) {
|
||||
throw new HttpException('refreshToken required', 400);
|
||||
}
|
||||
this.logger.log('Token refresh request');
|
||||
|
||||
this.logger.log('Token refresh request');
|
||||
|
||||
try {
|
||||
const res = await axios.post(this.graphqlUrl, {
|
||||
query: `mutation RefreshToken($token: String!) {
|
||||
try {
|
||||
const res = await axios.post(
|
||||
this.graphqlUrl,
|
||||
{
|
||||
query: `mutation RefreshToken($token: String!) {
|
||||
renewToken(appToken: $token) {
|
||||
tokens {
|
||||
accessOrWorkspaceAgnosticToken { token expiresAt }
|
||||
@@ -165,25 +189,29 @@ export class AuthController {
|
||||
}
|
||||
}
|
||||
}`,
|
||||
variables: { token: body.refreshToken },
|
||||
}, {
|
||||
headers: { 'Content-Type': 'application/json' },
|
||||
});
|
||||
variables: { token: body.refreshToken },
|
||||
},
|
||||
{
|
||||
headers: { 'Content-Type': 'application/json' },
|
||||
},
|
||||
);
|
||||
|
||||
if (res.data.errors) {
|
||||
this.logger.warn(`Token refresh failed: ${res.data.errors[0]?.message}`);
|
||||
throw new HttpException('Token refresh failed', 401);
|
||||
}
|
||||
if (res.data.errors) {
|
||||
this.logger.warn(
|
||||
`Token refresh failed: ${res.data.errors[0]?.message}`,
|
||||
);
|
||||
throw new HttpException('Token refresh failed', 401);
|
||||
}
|
||||
|
||||
const tokens = res.data.data.renewToken.tokens;
|
||||
return {
|
||||
accessToken: tokens.accessOrWorkspaceAgnosticToken.token,
|
||||
refreshToken: tokens.refreshToken.token,
|
||||
};
|
||||
} catch (error) {
|
||||
if (error instanceof HttpException) throw error;
|
||||
this.logger.error(`Token refresh failed: ${error}`);
|
||||
throw new HttpException('Token refresh failed', 401);
|
||||
}
|
||||
const tokens = res.data.data.renewToken.tokens;
|
||||
return {
|
||||
accessToken: tokens.accessOrWorkspaceAgnosticToken.token,
|
||||
refreshToken: tokens.refreshToken.token,
|
||||
};
|
||||
} catch (error) {
|
||||
if (error instanceof HttpException) throw error;
|
||||
this.logger.error(`Token refresh failed: ${error}`);
|
||||
throw new HttpException('Token refresh failed', 401);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user