From 03a4bcf6414f856640efdb7da3baf2c36b001d2a Mon Sep 17 00:00:00 2001 From: aarontravass <43901677+aarontravass@users.noreply.github.com> Date: Sat, 13 Jul 2024 04:17:34 -0400 Subject: [PATCH 1/3] Update README.md --- README.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/README.md b/README.md index 23a6a14..e298029 100644 --- a/README.md +++ b/README.md @@ -1 +1,3 @@ # Submission for MediHacks 2024 + +![Untitled](https://github.com/user-attachments/assets/64d1df45-553a-4e51-a8e9-6ca8d6e2f0a5) From 32e4a66538fd4cb1547369058cd2dc575e5adf23 Mon Sep 17 00:00:00 2001 From: aarontravass Date: Sun, 14 Jul 2024 00:00:29 -0400 Subject: [PATCH 2/3] fix: added host --- packages/upload/src/server.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/upload/src/server.ts b/packages/upload/src/server.ts index f0deff2..6ca5591 100644 --- a/packages/upload/src/server.ts +++ b/packages/upload/src/server.ts @@ -53,7 +53,7 @@ fastify.post('/upload', async (req, res) => { return res.status(200).send({ success: true }) }) -fastify.listen({ port: PORT }, (err) => { +fastify.listen({ port: PORT, host: '0.0.0.0' }, (err) => { if (err) throw err console.log(`server listening on ${PORT}`) }) From 502d9dceb6a25229b738beffa718ee953dfaeda3 Mon Sep 17 00:00:00 2001 From: aarontravass Date: Sun, 14 Jul 2024 01:55:36 -0400 Subject: [PATCH 3/3] docs: added readme --- README.md | 61 ++++++++++++++++++- package.json | 4 +- packages/platform/package.json | 4 +- packages/platform/src/builder.ts | 4 +- packages/platform/src/filebase.ts | 2 +- packages/platform/src/prisma.ts | 2 +- .../AuthToken/mutations/createAuthToken.ts | 2 +- .../mutations/createShareToken.ts | 4 +- .../mutations/revokeShareToken.ts | 2 +- .../FileShareToken/queries/listShareTokens.ts | 2 +- .../PatientFile/mutations/removeFile.ts | 2 +- .../queries/fetchPatientFileBlob.ts | 2 +- .../PatientFile/queries/fetchPatientFiles.ts | 2 +- .../PatientFile/queries/viewSharedFileBlob.ts | 11 +++- .../queries/fetchPatientStorage.ts | 2 +- .../mutations/generatePreSignedUploadUrl.ts | 2 +- .../resolvers/User/mutations/addPatient.ts | 2 +- .../User/queries/fetchAllPatients.ts | 2 +- .../resolvers/User/queries/fetchPatients.ts | 2 +- .../src/resolvers/User/queries/fetchUser.ts | 2 +- packages/platform/src/schema/UserRole.enum.ts | 2 +- packages/platform/src/ucan.ts | 2 +- packages/platform/src/utils.ts | 2 +- packages/platform/src/validation/auth.ts | 2 +- packages/prisma/package.json | 2 +- packages/upload/package.json | 4 +- packages/upload/src/filebase.ts | 2 +- packages/upload/src/prisma.ts | 2 +- packages/web/package.json | 2 +- pnpm-lock.yaml | 12 ++-- 30 files changed, 107 insertions(+), 41 deletions(-) diff --git a/README.md b/README.md index e298029..6184c7c 100644 --- a/README.md +++ b/README.md @@ -1,3 +1,60 @@ -# Submission for MediHacks 2024 +
+ +
-![Untitled](https://github.com/user-attachments/assets/64d1df45-553a-4e51-a8e9-6ca8d6e2f0a5) +
+ +[![CI](https://github.com/aarontravass/Athena/actions/workflows/ci.yml/badge.svg?branch=main)](https://github.com/aarontravass/Athena/actions/workflows/ci.yml) + +
+ +
+
+ +Data transparency and ownership are global challenges, with most patient health records controlled by providers. This centralization limits patient access and hinders data sharing across systems. + +A distributed, reliable, and transparent storage system is needed to enhance data accessibility, security, and empower patients with greater control over their health records. + +Athena is the modern EMR and EHR open source storage solution based on IPFS. Built on top of Filebase, it addresses problems with data ownership and transparency in the health sector. By leveraging blockchains, we can create a decentralized network that ensures data integrity and transparency, reducing the risk of data breaches and unauthorized access. + +### Table of Contents + +- [Features](#core-features) +- [Install](#install) +- [License](#license) + +## Features + +- **Distributed and scalable:** Built using GraphQL, Fastify and PostgreSQL, containerized via Docker and deployed on Vercel and Render. +- **Encryption in Transit:** All files are encrypted using AES-256. +- **Controlled sharing:** Share documents using signed links + +## Install + +Clone the repository + +```sh +git clone https://github.com/aarontravass/Athena.git +``` + +Install dependencies + +```sh +pnpm i +``` + +Generate prisma dist + +```sh +lerna run --scope @athena/prisma generate +``` + +Run web, server and upload package + +```sh +lerna run dev +``` + +## License + +Licensed under [MIT](./LICENSE). diff --git a/package.json b/package.json index 404eb52..71d4cda 100644 --- a/package.json +++ b/package.json @@ -19,8 +19,8 @@ }, "scripts": { "lint": "eslint .", - "format": "prettier --check \"./**/*.{ts,js,tsx}\"", - "format:fix": "prettier --write \"./**/*.{ts,js,tsx}\"", + "format": "prettier --check \"./**/*.{ts,js,tsx,md}\"", + "format:fix": "prettier --write \"./**/*.{ts,js,tsx,md}\"", "prepare": "husky" }, "packageManager": "pnpm@8.15.4", diff --git a/packages/platform/package.json b/packages/platform/package.json index e2599a3..beee033 100644 --- a/packages/platform/package.json +++ b/packages/platform/package.json @@ -1,5 +1,5 @@ { - "name": "@medihacks/platform", + "name": "@athena/platform", "version": "0.0.0", "description": "> TODO: description", "author": "aarontravass ", @@ -25,7 +25,7 @@ }, "dependencies": { "@aws-sdk/client-s3": "3.47.0", - "@medihacks/prisma": "workspace:^", + "@athena/prisma": "workspace:^", "@pothos/core": "^3.41.2", "@pothos/plugin-prisma": "^3.65.3", "@pothos/plugin-scope-auth": "^3.22.1", diff --git a/packages/platform/src/builder.ts b/packages/platform/src/builder.ts index 4228a23..603bf57 100644 --- a/packages/platform/src/builder.ts +++ b/packages/platform/src/builder.ts @@ -1,4 +1,4 @@ -import { Prisma, UserRole } from '@medihacks/prisma' +import { Prisma, UserRole } from '@athena/prisma' import SchemaBuilder from '@pothos/core' import PrismaPlugin from '@pothos/plugin-prisma' import { GraphQLError } from 'graphql' @@ -7,7 +7,7 @@ import { YogaInitialContext } from 'graphql-yoga' import { prisma } from './prisma' import ScopeAuthPlugin from '@pothos/plugin-scope-auth' import ValidationPlugin from '@pothos/plugin-validation' -import type PrismaTypes from '@medihacks/prisma/pothos-types' +import type PrismaTypes from '@athena/prisma/pothos-types' import { hasRole } from './validation/auth' export interface CustomContext extends YogaInitialContext { diff --git a/packages/platform/src/filebase.ts b/packages/platform/src/filebase.ts index 1c73dd1..1d0b0fa 100644 --- a/packages/platform/src/filebase.ts +++ b/packages/platform/src/filebase.ts @@ -1,6 +1,6 @@ import { S3 } from '@aws-sdk/client-s3' import { FILEBASE_ACCESS_KEY_ID, FILEBASE_S3_URL, FILEBASE_SECRET_ACCESS_KEY } from './constants' -import { PatientFile } from '@medihacks/prisma' +import { PatientFile } from '@athena/prisma' import { GraphQLError } from 'graphql' import { streamToBase64 } from './utils' diff --git a/packages/platform/src/prisma.ts b/packages/platform/src/prisma.ts index 41fe9ed..07be406 100644 --- a/packages/platform/src/prisma.ts +++ b/packages/platform/src/prisma.ts @@ -1,3 +1,3 @@ -import { PrismaClient } from '@medihacks/prisma' +import { PrismaClient } from '@athena/prisma' export const prisma = new PrismaClient({}) diff --git a/packages/platform/src/resolvers/AuthToken/mutations/createAuthToken.ts b/packages/platform/src/resolvers/AuthToken/mutations/createAuthToken.ts index 18de67d..c1799ee 100644 --- a/packages/platform/src/resolvers/AuthToken/mutations/createAuthToken.ts +++ b/packages/platform/src/resolvers/AuthToken/mutations/createAuthToken.ts @@ -6,7 +6,7 @@ import { generateAuthAndRefreshTokens } from '../../../utils' import { getUserFromPrivy } from '../../../privy' import { createBucket } from '../../../filebase' import { UserRoleEnum } from '../../../schema/UserRole.enum' -import { UserRole } from '@medihacks/prisma' +import { UserRole } from '@athena/prisma' builder.mutationField('createAuthToken', (t) => t.prismaField({ diff --git a/packages/platform/src/resolvers/FileShareToken/mutations/createShareToken.ts b/packages/platform/src/resolvers/FileShareToken/mutations/createShareToken.ts index 5e64598..e8d6ffc 100644 --- a/packages/platform/src/resolvers/FileShareToken/mutations/createShareToken.ts +++ b/packages/platform/src/resolvers/FileShareToken/mutations/createShareToken.ts @@ -1,4 +1,4 @@ -import { UserRole } from '@medihacks/prisma' +import { UserRole } from '@athena/prisma' import { builder } from '../../../builder' import { prisma } from '../../../prisma' import { GraphQLError } from 'graphql' @@ -29,7 +29,7 @@ builder.mutationField('createShareToken', (t) => }, FILE_TOKEN_JWT_KEY!, { - issuer: 'medihacks', + issuer: 'athena', expiresIn: ttl } ) diff --git a/packages/platform/src/resolvers/FileShareToken/mutations/revokeShareToken.ts b/packages/platform/src/resolvers/FileShareToken/mutations/revokeShareToken.ts index 4efe782..f8656d7 100644 --- a/packages/platform/src/resolvers/FileShareToken/mutations/revokeShareToken.ts +++ b/packages/platform/src/resolvers/FileShareToken/mutations/revokeShareToken.ts @@ -1,4 +1,4 @@ -import { UserRole } from '@medihacks/prisma' +import { UserRole } from '@athena/prisma' import { builder } from '../../../builder' import { prisma } from '../../../prisma' diff --git a/packages/platform/src/resolvers/FileShareToken/queries/listShareTokens.ts b/packages/platform/src/resolvers/FileShareToken/queries/listShareTokens.ts index 00bc859..fb55270 100644 --- a/packages/platform/src/resolvers/FileShareToken/queries/listShareTokens.ts +++ b/packages/platform/src/resolvers/FileShareToken/queries/listShareTokens.ts @@ -1,4 +1,4 @@ -import { UserRole } from '@medihacks/prisma' +import { UserRole } from '@athena/prisma' import { builder } from '../../../builder' import { FileShareToken } from '../../../schema/FileShareToken.schema' import { prisma } from '../../../prisma' diff --git a/packages/platform/src/resolvers/PatientFile/mutations/removeFile.ts b/packages/platform/src/resolvers/PatientFile/mutations/removeFile.ts index 4cdc595..fac47d4 100644 --- a/packages/platform/src/resolvers/PatientFile/mutations/removeFile.ts +++ b/packages/platform/src/resolvers/PatientFile/mutations/removeFile.ts @@ -1,4 +1,4 @@ -import { UserRole } from '@medihacks/prisma' +import { UserRole } from '@athena/prisma' import { builder } from '../../../builder' import { prisma } from '../../../prisma' import { GraphQLError } from 'graphql' diff --git a/packages/platform/src/resolvers/PatientFile/queries/fetchPatientFileBlob.ts b/packages/platform/src/resolvers/PatientFile/queries/fetchPatientFileBlob.ts index 493bbf8..f5e1d29 100644 --- a/packages/platform/src/resolvers/PatientFile/queries/fetchPatientFileBlob.ts +++ b/packages/platform/src/resolvers/PatientFile/queries/fetchPatientFileBlob.ts @@ -1,4 +1,4 @@ -import { UserRole } from '@medihacks/prisma' +import { UserRole } from '@athena/prisma' import { builder } from '../../../builder' import { prisma } from '../../../prisma' import { GraphQLError } from 'graphql' diff --git a/packages/platform/src/resolvers/PatientFile/queries/fetchPatientFiles.ts b/packages/platform/src/resolvers/PatientFile/queries/fetchPatientFiles.ts index bee1c08..ac5779c 100644 --- a/packages/platform/src/resolvers/PatientFile/queries/fetchPatientFiles.ts +++ b/packages/platform/src/resolvers/PatientFile/queries/fetchPatientFiles.ts @@ -1,4 +1,4 @@ -import { UserRole } from '@medihacks/prisma' +import { UserRole } from '@athena/prisma' import { builder } from '../../../builder' import { PatientFile } from '../../../schema/PatientFile.schema' import { prisma } from '../../../prisma' diff --git a/packages/platform/src/resolvers/PatientFile/queries/viewSharedFileBlob.ts b/packages/platform/src/resolvers/PatientFile/queries/viewSharedFileBlob.ts index f6c5807..4817e4e 100644 --- a/packages/platform/src/resolvers/PatientFile/queries/viewSharedFileBlob.ts +++ b/packages/platform/src/resolvers/PatientFile/queries/viewSharedFileBlob.ts @@ -2,6 +2,8 @@ import { GraphQLError } from 'graphql' import { builder } from '../../../builder' import { prisma } from '../../../prisma' import { fetchFileAsBase64 } from '../../../filebase' +import jsonwebtoken from 'jsonwebtoken' +import { FILE_TOKEN_JWT_KEY } from '../../../constants' builder.queryField('viewSharedFileBlob', (t) => t.string({ @@ -17,7 +19,14 @@ builder.queryField('viewSharedFileBlob', (t) => }) if (!shareToken) throw new GraphQLError('You do not have access to view this resource!') - return fetchFileAsBase64(shareToken.patientFile) + try { + jsonwebtoken.verify(token, FILE_TOKEN_JWT_KEY!, { + issuer: 'athena' + }) + return fetchFileAsBase64(shareToken.patientFile) + } catch (error) { + throw new GraphQLError('This link has expired') + } } }) ) diff --git a/packages/platform/src/resolvers/PatientStorage/queries/fetchPatientStorage.ts b/packages/platform/src/resolvers/PatientStorage/queries/fetchPatientStorage.ts index 13da02b..61758a7 100644 --- a/packages/platform/src/resolvers/PatientStorage/queries/fetchPatientStorage.ts +++ b/packages/platform/src/resolvers/PatientStorage/queries/fetchPatientStorage.ts @@ -1,4 +1,4 @@ -import { UserRole } from '@medihacks/prisma' +import { UserRole } from '@athena/prisma' import { builder } from '../../../builder' import { PatientStorage } from '../../../schema/PatientStorage.schema' import { prisma } from '../../../prisma' diff --git a/packages/platform/src/resolvers/PreSignedUrl/mutations/generatePreSignedUploadUrl.ts b/packages/platform/src/resolvers/PreSignedUrl/mutations/generatePreSignedUploadUrl.ts index 206b9c5..f877a71 100644 --- a/packages/platform/src/resolvers/PreSignedUrl/mutations/generatePreSignedUploadUrl.ts +++ b/packages/platform/src/resolvers/PreSignedUrl/mutations/generatePreSignedUploadUrl.ts @@ -1,4 +1,4 @@ -import { UserRole } from '@medihacks/prisma' +import { UserRole } from '@athena/prisma' import { builder } from '../../../builder' import { prisma } from '../../../prisma' import { UPLOAD_URL } from '../../../constants' diff --git a/packages/platform/src/resolvers/User/mutations/addPatient.ts b/packages/platform/src/resolvers/User/mutations/addPatient.ts index ec297de..adeaac8 100644 --- a/packages/platform/src/resolvers/User/mutations/addPatient.ts +++ b/packages/platform/src/resolvers/User/mutations/addPatient.ts @@ -1,4 +1,4 @@ -import { UserRole } from '@medihacks/prisma' +import { UserRole } from '@athena/prisma' import { builder } from '../../../builder' import { prisma } from '../../../prisma' import { GraphQLError } from 'graphql' diff --git a/packages/platform/src/resolvers/User/queries/fetchAllPatients.ts b/packages/platform/src/resolvers/User/queries/fetchAllPatients.ts index fa9db77..1d1867b 100644 --- a/packages/platform/src/resolvers/User/queries/fetchAllPatients.ts +++ b/packages/platform/src/resolvers/User/queries/fetchAllPatients.ts @@ -1,4 +1,4 @@ -import { UserRole } from '@medihacks/prisma' +import { UserRole } from '@athena/prisma' import { builder } from '../../../builder' import { User } from '../../../schema/User.schema' import { prisma } from '../../../prisma' diff --git a/packages/platform/src/resolvers/User/queries/fetchPatients.ts b/packages/platform/src/resolvers/User/queries/fetchPatients.ts index 90173f8..4129889 100644 --- a/packages/platform/src/resolvers/User/queries/fetchPatients.ts +++ b/packages/platform/src/resolvers/User/queries/fetchPatients.ts @@ -1,4 +1,4 @@ -import { UserRole } from '@medihacks/prisma' +import { UserRole } from '@athena/prisma' import { builder } from '../../../builder' import { User } from '../../../schema/User.schema' import { prisma } from '../../../prisma' diff --git a/packages/platform/src/resolvers/User/queries/fetchUser.ts b/packages/platform/src/resolvers/User/queries/fetchUser.ts index 3e08075..adb52af 100644 --- a/packages/platform/src/resolvers/User/queries/fetchUser.ts +++ b/packages/platform/src/resolvers/User/queries/fetchUser.ts @@ -1,4 +1,4 @@ -import { UserRole } from '@medihacks/prisma' +import { UserRole } from '@athena/prisma' import { builder } from '../../../builder' import { prisma } from '../../../prisma' import { User } from '../../../schema/User.schema' diff --git a/packages/platform/src/schema/UserRole.enum.ts b/packages/platform/src/schema/UserRole.enum.ts index 35cd32c..3d06bf3 100644 --- a/packages/platform/src/schema/UserRole.enum.ts +++ b/packages/platform/src/schema/UserRole.enum.ts @@ -1,4 +1,4 @@ -import { UserRole } from '@medihacks/prisma' +import { UserRole } from '@athena/prisma' import { builder } from '../builder' export const UserRoleEnum = builder.enumType(UserRole, { diff --git a/packages/platform/src/ucan.ts b/packages/platform/src/ucan.ts index df11881..545bd5a 100644 --- a/packages/platform/src/ucan.ts +++ b/packages/platform/src/ucan.ts @@ -1,6 +1,6 @@ import * as ucans from '@ucans/ucans' import { ED_SECRET_KEY, ORG_DID } from './constants' -import { User, UserRole } from '@medihacks/prisma' +import { User, UserRole } from '@athena/prisma' import { prisma } from './prisma' import { CustomContext } from './builder' diff --git a/packages/platform/src/utils.ts b/packages/platform/src/utils.ts index f649d0a..e689aba 100644 --- a/packages/platform/src/utils.ts +++ b/packages/platform/src/utils.ts @@ -1,4 +1,4 @@ -import { User } from '@medihacks/prisma' +import { User } from '@athena/prisma' import { createDecipheriv, randomUUID } from 'node:crypto' import { generateUCAN } from './ucan' import { FILE_ENCRYPTION_KEY } from './constants' diff --git a/packages/platform/src/validation/auth.ts b/packages/platform/src/validation/auth.ts index 8ac641b..d7a4503 100644 --- a/packages/platform/src/validation/auth.ts +++ b/packages/platform/src/validation/auth.ts @@ -2,7 +2,7 @@ import { CustomContext } from '../builder' import { verifyAuthToken } from '../privy' import { prisma } from '../prisma' import { parseUCAN, verifyUCAN } from '../ucan' -import { UserRole } from '@medihacks/prisma' +import { UserRole } from '@athena/prisma' export const fetchPrivyDidFromAuth = (authToken: string) => verifyAuthToken(authToken) diff --git a/packages/prisma/package.json b/packages/prisma/package.json index b5d2588..500d987 100644 --- a/packages/prisma/package.json +++ b/packages/prisma/package.json @@ -1,5 +1,5 @@ { - "name": "@medihacks/prisma", + "name": "@athena/prisma", "version": "0.0.0", "description": "> TODO: description", "author": "aarontravass ", diff --git a/packages/upload/package.json b/packages/upload/package.json index 0655b77..5cf13a1 100644 --- a/packages/upload/package.json +++ b/packages/upload/package.json @@ -1,5 +1,5 @@ { - "name": "@medihacks/upload", + "name": "@athena/upload", "version": "0.0.0", "description": "> TODO: description", "author": "aarontravass ", @@ -26,7 +26,7 @@ "@aws-sdk/client-s3": "3.47.0", "@fastify/cors": "^9.0.1", "@fastify/multipart": "^8.3.0", - "@medihacks/prisma": "workspace:^", + "@athena/prisma": "workspace:^", "fastify": "^4.28.1" }, "devDependencies": { diff --git a/packages/upload/src/filebase.ts b/packages/upload/src/filebase.ts index c52ae7b..acff624 100644 --- a/packages/upload/src/filebase.ts +++ b/packages/upload/src/filebase.ts @@ -1,6 +1,6 @@ import { S3 } from '@aws-sdk/client-s3' import { FILEBASE_ACCESS_KEY_ID, FILEBASE_S3_URL, FILEBASE_SECRET_ACCESS_KEY } from './constants' -import { User } from '@medihacks/prisma' +import { User } from '@athena/prisma' import type { MultipartFile } from '@fastify/multipart' import { encryptBuffer } from './utils' diff --git a/packages/upload/src/prisma.ts b/packages/upload/src/prisma.ts index 41fe9ed..07be406 100644 --- a/packages/upload/src/prisma.ts +++ b/packages/upload/src/prisma.ts @@ -1,3 +1,3 @@ -import { PrismaClient } from '@medihacks/prisma' +import { PrismaClient } from '@athena/prisma' export const prisma = new PrismaClient({}) diff --git a/packages/web/package.json b/packages/web/package.json index 02ced4b..fbeed26 100644 --- a/packages/web/package.json +++ b/packages/web/package.json @@ -1,5 +1,5 @@ { - "name": "@medihacks/web", + "name": "@athena/web", "version": "0.1.0", "author": "ashup99 ", "license": "MIT", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 9549213..dde81af 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -60,12 +60,12 @@ importers: packages/platform: dependencies: + '@athena/prisma': + specifier: workspace:^ + version: link:../prisma '@aws-sdk/client-s3': specifier: 3.47.0 version: 3.47.0(@aws-sdk/signature-v4-crt@3.609.0) - '@medihacks/prisma': - specifier: workspace:^ - version: link:../prisma '@pothos/core': specifier: ^3.41.2 version: 3.41.2(graphql@16.9.0) @@ -130,6 +130,9 @@ importers: packages/upload: dependencies: + '@athena/prisma': + specifier: workspace:^ + version: link:../prisma '@aws-sdk/client-s3': specifier: 3.47.0 version: 3.47.0(@aws-sdk/signature-v4-crt@3.609.0) @@ -139,9 +142,6 @@ importers: '@fastify/multipart': specifier: ^8.3.0 version: 8.3.0 - '@medihacks/prisma': - specifier: workspace:^ - version: link:../prisma fastify: specifier: ^4.28.1 version: 4.28.1