Skip to content

Commit

Permalink
feat: add desktop electron project for mac (#136)
Browse files Browse the repository at this point in the history
  • Loading branch information
cfu288 authored Mar 2, 2024
1 parent b13a38d commit 4f6c4e2
Show file tree
Hide file tree
Showing 82 changed files with 6,416 additions and 3,762 deletions.
8 changes: 4 additions & 4 deletions .github/workflows/production.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -30,14 +30,14 @@ jobs:

- name: Build and push
uses: docker/build-push-action@v5
env:
SENTRY_AUTH_TOKEN: ${{ secrets.SENTRY_AUTH_TOKEN }}
# env:
# SENTRY_AUTH_TOKEN: ${{ secrets.SENTRY_AUTH_TOKEN }}
with:
context: .
push: true
tags: cfu288/mere-medical:latest,cfu288/mere-medical:${{ env.RELEASE_CALVER_VERSION }}
secrets: |
SENTRY_AUTH_TOKEN=${{ secrets.SENTRY_AUTH_TOKEN }}
# secrets: |
# SENTRY_AUTH_TOKEN=${{ secrets.SENTRY_AUTH_TOKEN }}

- name: Create a GitHub release
uses: ncipollo/release-action@v1
Expand Down
39 changes: 27 additions & 12 deletions apps/api/src/app/app.module.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import { CernerModule } from './cerner/cerner.module';
import { EpicModule } from './epic/epic.module';
import { VeradigmModule } from './veradigm/veradigm.module';
import { TenantModule } from './tenant/tenant.module';
import { VAModule } from './va/va.module';
import { LoggerModule } from 'nestjs-pino';

const imports: ModuleMetadata['imports'] = [
Expand All @@ -16,6 +17,7 @@ const imports: ModuleMetadata['imports'] = [
EpicModule,
VeradigmModule,
TenantModule,
VAModule,
];

if (checkIfSentryConfigured()) {
Expand All @@ -37,7 +39,7 @@ if (checkIfSentryConfigured()) {
},
},
},
})
}),
);
} else {
imports.unshift(
Expand All @@ -46,17 +48,18 @@ if (checkIfSentryConfigured()) {
level: 'info',
transport: { target: 'pino-pretty' },
},
})
}),
);
}

if (checkIfOnPatientConfigured()) {
const opConfigured = checkIfOnPatientConfigured();
if (opConfigured.check) {
imports.push(
OnPatientModule.register({
clientId: process.env.ONPATIENT_CLIENT_ID,
clientSecret: process.env.ONPATIENT_CLIENT_SECRET,
clientId: opConfigured.clientId,
clientSecret: opConfigured.clientSecret,
redirectUri: `${process.env.PUBLIC_URL}/api/v1/onpatient/callback`,
})
}),
);
}

Expand All @@ -68,32 +71,44 @@ export class AppModule {}

// --- Helper functions ---

function checkIfOnPatientConfigured(): boolean {
function checkIfOnPatientConfigured():
| {
check: true;
clientId: string;
clientSecret: string;
}
| { check: false } {
const check =
!!process.env.ONPATIENT_CLIENT_ID && !!process.env.ONPATIENT_CLIENT_SECRET;
if (!process.env.ONPATIENT_CLIENT_ID) {
Logger.warn(
'ONPATIENT_CLIENT_ID was not provided: OnPatient services will be disabled.'
'ONPATIENT_CLIENT_ID was not provided: OnPatient services will be disabled.',
);
}
if (!process.env.ONPATIENT_CLIENT_SECRET) {
Logger.warn(
'ONPATIENT_CLIENT_SECRET was not provided: OnPatient services will be disabled.'
'ONPATIENT_CLIENT_SECRET was not provided: OnPatient services will be disabled.',
);
}
if (check) {
Logger.log(
'ONPATIENT_CLIENT_ID and ONPATIENT_CLIENT_SECRET were provided: OnPatient service will be enabled.'
'ONPATIENT_CLIENT_ID and ONPATIENT_CLIENT_SECRET were provided: OnPatient service will be enabled.',
);

return {
check,
clientId: process.env.ONPATIENT_CLIENT_ID!,
clientSecret: process.env.ONPATIENT_CLIENT_SECRET!,
};
}

return check;
return { check };
}

function checkIfSentryConfigured(): boolean {
if (!process.env.SENTRY_DSN) {
Logger.warn(
'SENTRY_DSN was not provided: Sentry logging will be disabled.'
'SENTRY_DSN was not provided: Sentry logging will be disabled.',
);
} else {
Logger.log('SENTRY_DSN was provided: Sentry logging will be enabled.');
Expand Down
2 changes: 1 addition & 1 deletion apps/api/src/app/cerner/cerner.controller.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ export class CernerController {
constructor(private readonly cernerService: CernerService) {}

@Get('tenants')
async getData(@Res() response: Response, @Query('query') query) {
async getData(@Res() response: Response, @Query('query') query: string) {
try {
const data = await this.cernerService.queryTenants(query);
response.json(data);
Expand Down
4 changes: 2 additions & 2 deletions apps/api/src/app/epic/epic.controller.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ export class EpicController {
async getDSTU2Tenants(
@NestRequest() request: Request,
@Res() response: Response,
@Query('query') query
@Query('query') query: string,
) {
try {
const data = await this.epicService.queryTenants(query);
Expand All @@ -29,7 +29,7 @@ export class EpicController {
}

@Get('tenants')
async getTenants(@Res() response: Response, @Query('query') query) {
async getTenants(@Res() response: Response, @Query('query') query: string) {
try {
const data = await this.epicService.queryTenants(query);
response.json(data);
Expand Down
4 changes: 2 additions & 2 deletions apps/api/src/app/onpatient/onpatient.controller.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,11 +7,11 @@ export class OnPatientController {
constructor(private readonly onPatientService: OnPatientService) {}

@Get('callback')
async getData(@Res() response: Response, @Query('code') code) {
async getData(@Res() response: Response, @Query('code') code: string) {
try {
const data = await this.onPatientService.getAuthCode(code);
response.redirect(
`${process.env.PUBLIC_URL}/onpatient/callback?accessToken=${data.access_token}&refreshToken=${data.refresh_token}&expiresIn=${data.expires_in}`
`${process.env.PUBLIC_URL}/onpatient/callback?accessToken=${data.access_token}&refreshToken=${data.refresh_token}&expiresIn=${data.expires_in}`,
);
} catch (e) {
Logger.error(e);
Expand Down
19 changes: 13 additions & 6 deletions apps/api/src/app/onpatient/onpatient.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ export class OnPatientService {

constructor(
@Inject('CONFIG') private options: OnPatientServiceConfig,
private readonly httpService: HttpService
private readonly httpService: HttpService,
) {
this.envConfig = options;
}
Expand All @@ -24,7 +24,7 @@ export class OnPatientService {
if (!code) {
throw new HttpException(
'Forbidden: no auth code provided in callback url',
HttpStatus.FORBIDDEN
HttpStatus.FORBIDDEN,
);
}

Expand All @@ -39,20 +39,27 @@ export class OnPatientService {
const response = await this.httpService.post<OnPatientAuthResponse>(
'https://onpatient.com/o/token/?' + new URLSearchParams(params),
null,
{ method: 'POST' }
{ method: 'POST' },
);

const awaitedRes = await response.toPromise();
const status = await awaitedRes.status;
const status = await awaitedRes?.status;

if (status !== 200) {
throw new HttpException(
'Forbidden: unable to get auth token with code',
HttpStatus.FORBIDDEN
HttpStatus.FORBIDDEN,
);
}

const data = await awaitedRes.data;
const data = await awaitedRes?.data;

if (!data) {
throw new HttpException(
'Forbidden: unable to get auth token with code',
HttpStatus.FORBIDDEN,
);
}

return data;
}
Expand Down
4 changes: 2 additions & 2 deletions apps/api/src/app/proxy/controllers/proxy.controller.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,11 +19,11 @@ export class ProxyController {
async proxy(
@Res() response: Response,
@NestRequest() request: Request,
@Param() params
@Param() params: any,
) {
try {
Logger.debug(
`Proxy request was made with params: ${JSON.stringify(params)}`
`Proxy request was made with params: ${JSON.stringify(params)}`,
);
this.proxyService.proxyRequest(request, response, params);
} catch (err) {
Expand Down
10 changes: 6 additions & 4 deletions apps/api/src/app/proxy/proxy.module.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
// @ts-nocheck
// import { EpicDSTU2TenantEndpoints } from '@mere/epic';
import { DynamicModule, Logger, Module, Provider } from '@nestjs/common';
import { createProxyServer } from 'http-proxy';
Expand Down Expand Up @@ -35,7 +36,8 @@ const proxyFactory = {
cookies = cookies
.split(';')
.filter(
(cookie) => allowedCookies.indexOf(cookie.split('=')[0].trim()) !== -1
(cookie) =>
allowedCookies.indexOf(cookie.split('=')[0].trim()) !== -1,
)
.join(';');

Expand Down Expand Up @@ -65,7 +67,7 @@ const proxyFactory = {
proxy.on('proxyRes', function (proxyRes, req, res) {
const url = concatPath(
`${proxyRes['req'].protocol}//${proxyRes['req'].host}`,
req.url
req.url,
);
logger.debug(`Received ${req.method} ${url}`);
});
Expand Down Expand Up @@ -100,7 +102,7 @@ export class ProxyModule {
}

private static createAsyncProviders(
options: ProxyModuleAsyncOptions
options: ProxyModuleAsyncOptions,
): Provider[] {
if (options.useExisting || options.useFactory) {
return [this.createAsyncOptionsProvider(options)];
Expand All @@ -115,7 +117,7 @@ export class ProxyModule {
}

private static createAsyncOptionsProvider(
options: ProxyModuleAsyncOptions
options: ProxyModuleAsyncOptions,
): Provider {
if (options.useFactory) {
return {
Expand Down
22 changes: 13 additions & 9 deletions apps/api/src/app/proxy/services/proxy.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,11 +10,15 @@ export class ProxyService {
private readonly logger = new Logger(ProxyService.name);

constructor(
@Inject(HTTP_PROXY) private proxy: server | any,
@Inject(PROXY_MODULE_OPTIONS) private options: ProxyModuleOptions
@Inject(HTTP_PROXY) private proxy: server,
@Inject(PROXY_MODULE_OPTIONS) private options: ProxyModuleOptions,
) {}

async proxyRequest(req: Request, res: Response, @Param() params?) {
async proxyRequest(
req: Request,
res: Response,
@Param() params?: Record<string, string>,
) {
const target = req.query.target as string;
const target_type = req.query.target_type as string;
let serviceId = (req.query.serviceId as string).trim();
Expand Down Expand Up @@ -45,7 +49,7 @@ export class ProxyService {
const services = new Map(
this.options.services
? this.options.services.map((service) => [service.id, service])
: []
: [],
);
// Temp workaround for sandbox
const isSandbox =
Expand All @@ -56,7 +60,7 @@ export class ProxyService {
}

if (services.has(serviceId) || isSandbox) {
const service = services.get(serviceId);
const service = services.get(serviceId)!;
this.logger.debug(`Proxying ${req.method} ${req.url} to ${serviceId}`);
const baseUrl = service.url;
const authUrl = service.authorize;
Expand All @@ -71,7 +75,7 @@ export class ProxyService {
urlToProxy =
(baseUrl.replace('/api/FHIR/DSTU2/', '') || '').replace(
'api/FHIR/DSTU2',
''
'',
) + '/oauth2/register';
}

Expand All @@ -80,7 +84,7 @@ export class ProxyService {
res,
target ? concatPath(urlToProxy, prefix, target) : urlToProxy,
service.forwardToken === false ? null : token,
{ ...service.config, headers }
{ ...service.config, headers },
);
} else {
const error = `Could not find serviceId '${serviceId}'`;
Expand Down Expand Up @@ -108,7 +112,7 @@ export class ProxyService {
res: Response,
target: string,
token: string,
options: server.ServerOptions = {}
options: server.ServerOptions = {},
) {
const url = new URL(target);
req.url = `${url.pathname}${url.search}`;
Expand All @@ -128,7 +132,7 @@ export class ProxyService {
...(options && options.headers),
}; // To deep extend headers

this.proxy.web(req, res, requestOptions, (err) => {
this.proxy.web(req, res, requestOptions, (err: any) => {
if (err.code === 'ECONNRESET') return;

this.logger.error({
Expand Down
4 changes: 2 additions & 2 deletions apps/api/src/app/proxy/utils/url.utils.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { URL } from 'url';

export function getBaseURL(path) {
export function getBaseURL(path: string) {
const url = new URL(path);
return url.origin;
}
Expand All @@ -9,7 +9,7 @@ export function concatPath(...args: string[]) {
return urlJoin(...args);
}

export function isAbsolute(path) {
export function isAbsolute(path: string) {
return !path.indexOf('/');
}

Expand Down
5 changes: 2 additions & 3 deletions apps/api/src/app/tenant/tenant.controller.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,10 +9,9 @@ export class TenantController {
@Get('/')
async getData(
@Res() response: Response,
@Query('query') query,
@Query('vendor') vendors
@Query('query') query: string,
@Query('vendor') vendors: string[],
) {
console.log('vendors', vendors);
try {
const data = await this.tenantService.queryTenants(query, vendors);
response.json(data);
Expand Down
Loading

0 comments on commit 4f6c4e2

Please sign in to comment.