snowballtools-base/packages/backend/src/resolvers.ts
Nabarun Gogoi ef0eac8293
Implement authentication with SIWE (#99)
* Create web3 modal provider with SIWE

* Add auth router to handle SIWE authentication

* Use axios instance to make request

* Add button for SIWE authentication

* Add changes to access session in web-app GQL requests

* Add auth check in GQL context and load/create user

* Use authenticated user from context

* Redirect to sign in page if unauthenticated and logout button

* Change sign-in route to login

* Get project domain from config file

* Set user ethAddress column as unique

* Use formatted user name

* Get session secret and origin url from config file

* Add unique constraint for eth address

* Get secure and samesite from origin url

* Get wallet connect id and backend url from env file

* Format user email in member tab panel

* Add backend config isProduction to set trust proxy

* Use only one server url config

* Add tool tip for displaying email

* Add trustProxy and domain in server.session config

* Add SERVER_GQL_PATH constant in frontend

---------

Co-authored-by: neeraj <neeraj.rtly@gmail.com>
2024-02-22 17:26:26 +05:30

220 lines
6.8 KiB
TypeScript

import debug from 'debug';
import { DeepPartial, FindOptionsWhere } from 'typeorm';
import { Service } from './service';
import { Permission } from './entity/ProjectMember';
import { Domain } from './entity/Domain';
import { Project } from './entity/Project';
import { EnvironmentVariable } from './entity/EnvironmentVariable';
const log = debug('snowball:resolver');
export const createResolvers = async (service: Service): Promise<any> => {
return {
Query: {
// TODO: add custom type for context
user: (_: any, __: any, context: any) => {
return context.user;
},
organizations: async (_:any, __: any, context: any) => {
return service.getOrganizationsByUserId(context.user);
},
project: async (_: any, { projectId }: { projectId: string }) => {
return service.getProjectById(projectId);
},
projectsInOrganization: async (_: any, { organizationSlug }: {organizationSlug: string }, context: any) => {
return service.getProjectsInOrganization(context.user, organizationSlug);
},
deployments: async (_: any, { projectId }: { projectId: string }) => {
return service.getDeploymentsByProjectId(projectId);
},
environmentVariables: async (_: any, { projectId }: { projectId: string }) => {
return service.getEnvironmentVariablesByProjectId(projectId);
},
projectMembers: async (_: any, { projectId }: { projectId: string }) => {
return service.getProjectMembersByProjectId(projectId);
},
searchProjects: async (_: any, { searchText }: { searchText: string }, context: any) => {
return service.searchProjects(context.user, searchText);
},
domains: async (_:any, { projectId, filter }: { projectId: string, filter?: FindOptionsWhere<Domain> }) => {
return service.getDomainsByProjectId(projectId, filter);
}
},
// TODO: Return error in GQL response
Mutation: {
removeProjectMember: async (_: any, { projectMemberId }: { projectMemberId: string }, context: any) => {
try {
return await service.removeProjectMember(context.user, projectMemberId);
} catch (err) {
log(err);
return false;
}
},
updateProjectMember: async (_: any, { projectMemberId, data }: {
projectMemberId: string,
data: {
permissions: Permission[]
}
}) => {
try {
return await service.updateProjectMember(projectMemberId, data);
} catch (err) {
log(err);
return false;
}
},
addProjectMember: async (_: any, { projectId, data }: {
projectId: string,
data: {
email: string,
permissions: Permission[]
}
}) => {
try {
return Boolean(await service.addProjectMember(projectId, data));
} catch (err) {
log(err);
return false;
}
},
addEnvironmentVariables: async (_: any, { projectId, data }: { projectId: string, data: { environments: string[], key: string, value: string}[] }) => {
try {
return Boolean(await service.addEnvironmentVariables(projectId, data));
} catch (err) {
log(err);
return false;
}
},
updateEnvironmentVariable: async (_: any, { environmentVariableId, data }: { environmentVariableId: string, data : DeepPartial<EnvironmentVariable>}) => {
try {
return await service.updateEnvironmentVariable(environmentVariableId, data);
} catch (err) {
log(err);
return false;
}
},
removeEnvironmentVariable: async (_: any, { environmentVariableId }: { environmentVariableId: string}) => {
try {
return await service.removeEnvironmentVariable(environmentVariableId);
} catch (err) {
log(err);
return false;
}
},
updateDeploymentToProd: async (_: any, { deploymentId }: { deploymentId: string }, context: any) => {
try {
return Boolean(await service.updateDeploymentToProd(context.user, deploymentId));
} catch (err) {
log(err);
return false;
}
},
addProject: async (_: any, { organizationSlug, data }: { organizationSlug: string, data: DeepPartial<Project> }, context: any) => {
try {
return await service.addProject(context.user, organizationSlug, data);
} catch (err) {
log(err);
throw err;
}
},
updateProject: async (_: any, { projectId, data }: { projectId: string, data: DeepPartial<Project> }) => {
try {
return await service.updateProject(projectId, data);
} catch (err) {
log(err);
return false;
}
},
redeployToProd: async (_: any, { deploymentId }: { deploymentId: string }, context: any) => {
try {
return Boolean(await service.redeployToProd(context.user, deploymentId));
} catch (err) {
log(err);
return false;
}
},
deleteProject: async (_: any, { projectId }: { projectId: string }) => {
try {
return await service.deleteProject(projectId);
} catch (err) {
log(err); return false;
}
},
deleteDomain: async (_: any, { domainId }: { domainId: string }) => {
try {
return await service.deleteDomain(domainId);
} catch (err) {
log(err);
return false;
}
},
rollbackDeployment: async (_: any, { projectId, deploymentId }: {deploymentId: string, projectId: string }) => {
try {
return await service.rollbackDeployment(projectId, deploymentId);
} catch (err) {
log(err);
return false;
}
},
addDomain: async (_: any, { projectId, data }: { projectId: string, data: { name: string } }) => {
try {
return Boolean(await service.addDomain(projectId, data));
} catch (err) {
log(err);
return false;
}
},
updateDomain: async (_: any, { domainId, data }: { domainId: string, data: DeepPartial<Domain>}) => {
try {
return await service.updateDomain(domainId, data);
} catch (err) {
log(err);
return false;
}
},
authenticateGitHub: async (_: any, { code }: { code: string }, context: any) => {
try {
return await service.authenticateGitHub(code, context.user);
} catch (err) {
log(err);
return false;
}
},
unauthenticateGitHub: async (_: any, __: object, context: any) => {
try {
return service.unauthenticateGitHub(context.user, { gitHubToken: null });
} catch (err) {
log(err);
return false;
}
}
}
};
};