From 29f0c8f7e8c85316eab390d10fa4e4355538a4b3 Mon Sep 17 00:00:00 2001 From: Thorsten Schau Date: Thu, 2 Feb 2023 16:41:08 +0100 Subject: [PATCH] add New Translator Orga Permissions Group. --- package.json | 2 +- src/environment.ts | 124 ++++-------- src/resolvers/mutations/addNewLang.ts | 24 +-- .../mutations/createNewStringAndKey.ts | 12 +- .../mutations/setStringUpdateState.ts | 10 +- src/resolvers/mutations/updatei18nValue.ts | 50 ++--- src/resolvers/mutations/verifySafe.ts | 60 +++--- src/resolvers/queries/sessionInfo.ts | 186 +++++++++--------- src/utils/canAccess.ts | 90 +++++---- 9 files changed, 260 insertions(+), 298 deletions(-) diff --git a/package.json b/package.json index a05cf591..55291417 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@o-platform/api-server", - "version": "0.1.516", + "version": "0.1.518", "description": "", "main": "dist/index.js", "prepublish": "tsc", diff --git a/src/environment.ts b/src/environment.ts index 669c3071..30238861 100644 --- a/src/environment.ts +++ b/src/environment.ts @@ -6,7 +6,7 @@ import AWS from "aws-sdk"; import { Pool } from "pg"; import fetch from "cross-fetch"; import { PrismaClient } from "./api-db/client"; -import {Generate} from "./utils/generate"; +import { Generate } from "./utils/generate"; export type SmtpConfig = { from: string; @@ -20,9 +20,8 @@ export type SmtpConfig = { }; export class Environment { - - static async validateAndSummarize(logInfo:boolean = true) { - const errors:string[] = []; + static async validateAndSummarize(logInfo: boolean = true) { + const errors: string[] = []; if (!this.corsOrigins) { errors.push(`The CORS_ORIGNS environment variable is not set.`); @@ -31,22 +30,16 @@ export class Environment { errors.push(`The APP_URL environment variable is not set.`); } if (!this.blockchainIndexerUrl) { - errors.push( - `The BLOCKCHAIN_INDEX_WS_URL environment variable is not set.` - ); + errors.push(`The BLOCKCHAIN_INDEX_WS_URL environment variable is not set.`); } if (!this.rpcGatewayUrl) { errors.push(`The RPC_GATEWAY_URL environment variable is not set.`); } if (!this.readonlyApiConnectionString) { - errors.push( - `The CONNECTION_STRING_RO environment variable is not set.` - ); + errors.push(`The CONNECTION_STRING_RO environment variable is not set.`); } if (!this.readWriteApiConnectionString) { - errors.push( - `The CONNECTION_STRING_RW environment variable is not set.` - ); + errors.push(`The CONNECTION_STRING_RW environment variable is not set.`); } if (!this.appId) { errors.push(`The APP_ID environment variable is not set.`); @@ -55,35 +48,23 @@ export class Environment { errors.push(`The EXTERNAL_DOMAIN environment variable is not set.`); } if (!this.operatorOrganisationAddress) { - errors.push( - `The OPERATOR_ORGANISATION_ADDRESS environment variable is not set.` - ); + errors.push(`The OPERATOR_ORGANISATION_ADDRESS environment variable is not set.`); } if (!this.pathfinderUrl) { - errors.push( - `The PATHFINDER_URL environment variable is not set.` - ); + errors.push(`The PATHFINDER_URL environment variable is not set.`); } if (logInfo) { - console.log( - `* Testing connection to the json rpc gateway (${this.rpcGatewayUrl}) ...` - ); + console.log(`* Testing connection to the json rpc gateway (${this.rpcGatewayUrl}) ...`); } - const rpcGateway = await fetch( - this.rpcGatewayUrl - .replace("ws://", "http://") - .replace("wss://", "https://") - ); + const rpcGateway = await fetch(this.rpcGatewayUrl.replace("ws://", "http://").replace("wss://", "https://")); if (rpcGateway.status < 500) { if (logInfo) { console.log(" Success. Body: " + (await rpcGateway.text())); } } else { errors.push( - `The json rpc gateway responded with a non 200 code: ${ - rpcGateway.status - }. Body: ${await rpcGateway.text()}` + `The json rpc gateway responded with a non 200 code: ${rpcGateway.status}. Body: ${await rpcGateway.text()}` ); } @@ -98,9 +79,7 @@ export class Environment { console.log(` ${this.operatorOrganisationAddress} nonce is: ${nonce}`); } if (!process.env.INVITATION_FUNDS_SAFE_ADDRESS) { - errors.push( - `The INVITATION_FUNDS_SAFE_ADDRESS environment variable is not set.` - ); + errors.push(`The INVITATION_FUNDS_SAFE_ADDRESS environment variable is not set.`); } if (logInfo) { @@ -111,18 +90,14 @@ export class Environment { console.log(` ${this.invitationFundsSafe.address} nonce is: ${nonce}`); } if (!process.env.INVITATION_FUNDS_SAFE_KEY) { - errors.push( - `The INVITATION_FUNDS_SAFE_KEY environment variable is not set.` - ); + errors.push(`The INVITATION_FUNDS_SAFE_KEY environment variable is not set.`); } if (logInfo) { console.log(`* Checking GCS_CREDENTIALS ...`); } if (!this.googleCloudStorageCredentials?.project_id) { - errors.push( - `The GCS_CREDENTIALS environment variable contains an invalid json object.` - ); + errors.push(`The GCS_CREDENTIALS environment variable contains an invalid json object.`); } else if (logInfo) { console.log(` Success:`); console.log(` project_id:`, this.googleCloudStorageCredentials?.project_id); @@ -134,9 +109,7 @@ export class Environment { console.log(`* Checking GCS_AVATAR_BUCKET ...`); } if (!this.avatarBucketName) { - errors.push( - `The GCS_AVATAR_BUCKET environment variable is not set.` - ); + errors.push(`The GCS_AVATAR_BUCKET environment variable is not set.`); } else if (logInfo) { console.log(` Success:`); console.log(` bucket name:`, this.avatarBucketName); @@ -170,14 +143,10 @@ export class Environment { if (logInfo) { console.log(` Success`); - console.log( - `* Testing connection to the indexer ws endpoint (${this.blockchainIndexerUrl}) ...` - ); + console.log(`* Testing connection to the indexer ws endpoint (${this.blockchainIndexerUrl}) ...`); } - let u = this.blockchainIndexerUrl - .replace("ws://", "http://") - .replace("wss://", "https://"); + let u = this.blockchainIndexerUrl.replace("ws://", "http://").replace("wss://", "https://"); if (!u.endsWith("/")) { u += "/"; @@ -193,9 +162,7 @@ export class Environment { } } else { const body = await indexerWsEndpoint.text(); - errors.push( - `The indexer ws endpoint responded with a non 200 code: ${indexerWsEndpoint.status}. Body: ${body}` - ); + errors.push(`The indexer ws endpoint responded with a non 200 code: ${indexerWsEndpoint.status}. Body: ${body}`); } if (errors.length > 0) { @@ -221,20 +188,20 @@ export class Environment { } private static _instanceId = Generate.randomBase64String(8).substr(0, 8); - static get instanceId() : string { + static get instanceId(): string { return this._instanceId; } static get keyRotationInterval(): number { - return 24 * 60 * 60 * 1000; + return 24 * 60 * 60 * 1000; } - static get periodicTaskInterval() : number { - return 5 * 60 * 1000; + static get periodicTaskInterval(): number { + return 5 * 60 * 1000; } - static get maxKeyAge() : number { - return 2 * this.keyRotationInterval; + static get maxKeyAge(): number { + return 2 * this.keyRotationInterval; } private static _indexDb: Pool = new Pool({ @@ -250,10 +217,12 @@ export class Environment { private static _pgReadWriteApiDb: Pool = new Pool({ connectionString: process.env.CONNECTION_STRING_RW, //ssl: !process.env.DEBUG, - ssl: process.env.API_DB_SSL_CERT ? { - cert: process.env.API_DB_SSL_CERT, - ca: process.env.API_DB_SSL_CA - } : undefined + ssl: process.env.API_DB_SSL_CERT + ? { + cert: process.env.API_DB_SSL_CERT, + ca: process.env.API_DB_SSL_CA, + } + : undefined, }).on("error", (err) => { console.error("An idle client has experienced an error", err.stack); }); @@ -320,10 +289,7 @@ export class Environment { } static get sessionLifetimeInSeconds(): number { - return parseInt( - process.env.SESSION_LIIFETIME ?? - (60 * 60 * 24 * 30).toString() - ); + return parseInt(process.env.SESSION_LIIFETIME ?? (60 * 60 * 24 * 30).toString()); } static get appId(): string { @@ -370,25 +336,20 @@ export class Environment { */ static get operatorOrganisationAddress(): string { // TODO: Remove default value "Basic Income Lab - Test Orga" - return ( - (process.env.OPERATOR_ORGANISATION_ADDRESS ?? - "0xc5a786eafefcf703c114558c443e4f17969d9573") - ); + return (process.env.OPERATOR_ORGANISATION_ADDRESS ?? "0xc5a786eafefcf703c114558c443e4f17969d9573"); + } + static get translatorOrganisationAddress(): string { + // TODO: Remove default value "Basic Income Lab - Test Orga" + return (process.env.TRANSLATOR_ORGANISATION_ADDRESS ?? "0xe3F306f70A3FFDD20c7b26B3ad3650Cc31e5D84A"); } - static get circlesHubAddress(): string { - return ( - (process.env.CIRCLES_HUB_ADDRESS?.toLowerCase() ?? - "0x29b9a7fBb8995b2423a71cC17cf9810798F6C543") - ); + return (process.env.CIRCLES_HUB_ADDRESS?.toLowerCase() ?? "0x29b9a7fBb8995b2423a71cC17cf9810798F6C543"); } static get invitationFundsSafe(): GnosisSafeProxy { return new GnosisSafeProxy( RpcGateway.get(), - RpcGateway.get().utils.toChecksumAddress( - process.env.INVITATION_FUNDS_SAFE_ADDRESS - ) + RpcGateway.get().utils.toChecksumAddress(process.env.INVITATION_FUNDS_SAFE_ADDRESS) ); } @@ -398,7 +359,7 @@ export class Environment { ); } - static get googleCloudStorageCredentials(): GoogleCloudCredentials|undefined { + static get googleCloudStorageCredentials(): GoogleCloudCredentials | undefined { try { return JSON.parse(process.env.GCS_CREDENTIALS); } catch { @@ -415,8 +376,7 @@ export class Environment { */ static get invitationFundsAmount(): BN { return new BN( - process.env.INVITATION_FUNDS_AMOUNT ?? - RpcGateway.get().utils.toWei("0.1", "ether") + process.env.INVITATION_FUNDS_AMOUNT ?? RpcGateway.get().utils.toWei("0.1", "ether") ); } } @@ -426,5 +386,5 @@ export type GoogleCloudCredentials = { project_id?: string; client_email?: string; private_key?: string; - [x:string]: any -} + [x: string]: any; +}; diff --git a/src/resolvers/mutations/addNewLang.ts b/src/resolvers/mutations/addNewLang.ts index d9e56e81..0ab1eff9 100644 --- a/src/resolvers/mutations/addNewLang.ts +++ b/src/resolvers/mutations/addNewLang.ts @@ -1,15 +1,16 @@ -import {MutationAddNewLangArgs} from "../../types"; -import {Context} from "../../context"; -import {isBILMember} from "../../utils/canAccess"; -import {Environment} from "../../environment"; +import { MutationAddNewLangArgs } from "../../types"; +import { Context } from "../../context"; +import { isTranslator } from "../../utils/canAccess"; +import { Environment } from "../../environment"; export const addNewLang = async (parent: any, args: MutationAddNewLangArgs, context: Context) => { const callerInfo = await context.callerInfo; - const isBilMember = await isBILMember(callerInfo?.profile?.circlesAddress); - if (!isBilMember) { - throw new Error (`You need to be a member of Basic Income Lab to add a new Language.`) + const canTranslate = await isTranslator(callerInfo?.profile?.circlesAddress); + if (!canTranslate) { + throw new Error(`You need to be a member of the Translator Orga to add or edit Translations.`); } else { - const queryResult = await Environment.pgReadWriteApiDb.query(` + const queryResult = await Environment.pgReadWriteApiDb.query( + ` insert into i18n (lang, key, "createdBy", version, value) select $1 as lang , i18n.key @@ -26,7 +27,8 @@ export const addNewLang = async (parent: any, args: MutationAddNewLangArgs, cont and i18n.lang = max_versions.lang and i18n.version = max_versions.version; `, - [args.langToCreate, args.langToCopyFrom]); - return queryResult.rowCount + [args.langToCreate, args.langToCopyFrom] + ); + return queryResult.rowCount; } -} +}; diff --git a/src/resolvers/mutations/createNewStringAndKey.ts b/src/resolvers/mutations/createNewStringAndKey.ts index fde487bd..d17cb06a 100644 --- a/src/resolvers/mutations/createNewStringAndKey.ts +++ b/src/resolvers/mutations/createNewStringAndKey.ts @@ -1,13 +1,13 @@ import { Context } from "../../context"; import { Environment } from "../../environment"; import { MutationCreateNewStringAndKeyArgs } from "../../types"; -import { isBILMember } from "../../utils/canAccess"; +import { isTranslator } from "../../utils/canAccess"; export const createNewStringAndKey = async (parent: any, args: MutationCreateNewStringAndKeyArgs, context: Context) => { let callerInfo = await context.callerInfo; - let isBilMember = await isBILMember(callerInfo?.profile?.circlesAddress); - if (!isBilMember) { - throw new Error(`Your need to be a member of Basic Income Lab to edit the content.`); + let canTranslate = await isTranslator(callerInfo?.profile?.circlesAddress); + if (!canTranslate) { + throw new Error(`You need to be a member of the Translator Orga to add or edit Translations.`); } else { let createdBy = callerInfo?.profile?.circlesAddress; const queryResult = await Environment.pgReadWriteApiDb.query( @@ -49,7 +49,7 @@ export const createNewStringAndKey = async (parent: any, args: MutationCreateNew `, [args.key] ); - + return newEntry; } -} \ No newline at end of file +}; diff --git a/src/resolvers/mutations/setStringUpdateState.ts b/src/resolvers/mutations/setStringUpdateState.ts index 2c9d41b1..600fd65c 100644 --- a/src/resolvers/mutations/setStringUpdateState.ts +++ b/src/resolvers/mutations/setStringUpdateState.ts @@ -1,13 +1,13 @@ import { Context } from "../../context"; import { Environment } from "../../environment"; import { MutationSetStringUpdateStateArgs } from "../../types"; -import { isBILMember } from "../../utils/canAccess"; +import { isTranslator } from "../../utils/canAccess"; export const setStringUpdateState = async (parent: any, args: MutationSetStringUpdateStateArgs, context: Context) => { let callerInfo = await context.callerInfo; - let isBilMember = await isBILMember(callerInfo?.profile?.circlesAddress); - if (!isBilMember) { - throw new Error(`Your need to be a member of Basic Income Lab to edit the content.`); + let canTranslate = await isTranslator(callerInfo?.profile?.circlesAddress); + if (!canTranslate) { + throw new Error(`You need to be a member of the Translator Orga to add or edit Translations.`); } else { let queryResult = await Environment.pgReadWriteApiDb.query( ` @@ -20,4 +20,4 @@ export const setStringUpdateState = async (parent: any, args: MutationSetStringU ); return queryResult.rows[0]; } -} \ No newline at end of file +}; diff --git a/src/resolvers/mutations/updatei18nValue.ts b/src/resolvers/mutations/updatei18nValue.ts index 393794cd..121bea86 100644 --- a/src/resolvers/mutations/updatei18nValue.ts +++ b/src/resolvers/mutations/updatei18nValue.ts @@ -1,17 +1,18 @@ -import {MutationUpdateValueArgs} from "../../types"; -import {Context} from "../../context"; -import {isBILMember} from "../../utils/canAccess"; -import {Environment} from "../../environment"; +import { MutationUpdateValueArgs } from "../../types"; +import { Context } from "../../context"; +import { isTranslator } from "../../utils/canAccess"; +import { Environment } from "../../environment"; export const updatei18nValue = async (parent: any, args: MutationUpdateValueArgs, context: Context) => { let callerInfo = await context.callerInfo; - let isBilMember = await isBILMember(callerInfo?.profile?.circlesAddress); + let canTranslate = await isTranslator(callerInfo?.profile?.circlesAddress); - if (!isBilMember) { - throw new Error(`You need to be a member of Basic Income Lab to edit the content.`) + if (!canTranslate) { + throw new Error(`You need to be a member of the Translator Orga to add or edit Translations.`); } else { - let createdBy = callerInfo?.profile?.circlesAddress - const queryResult = await Environment.pgReadWriteApiDb.query(` + let createdBy = callerInfo?.profile?.circlesAddress; + const queryResult = await Environment.pgReadWriteApiDb.query( + ` insert into i18n ( "needsUpdate", lang, @@ -29,32 +30,33 @@ export const updatei18nValue = async (parent: any, args: MutationUpdateValueArgs where key=$2 and lang=$1), $4) returning lang, key, "createdBy", version, value, "needsUpdate"; `, - [args.lang, args.key, createdBy, args.value]); + [args.lang, args.key, createdBy, args.value] + ); - const newEntry = queryResult.rows[0]; + const newEntry = queryResult.rows[0]; - await Environment.pgReadWriteApiDb.query( - ` + await Environment.pgReadWriteApiDb.query( + ` update i18n set "needsUpdate" = false where lang = $1 and key = $2; `, - [args.lang, args.key] - ); + [args.lang, args.key] + ); - if (args.lang?.startsWith("en")) { - await Environment.pgReadWriteApiDb.query( - ` + if (args.lang?.startsWith("en")) { + await Environment.pgReadWriteApiDb.query( + ` update i18n set "needsUpdate" = true where lang != 'en' and key = $1; `, - [args.key] - ); - } - - return newEntry; + [args.key] + ); + } + + return newEntry; } -} +}; diff --git a/src/resolvers/mutations/verifySafe.ts b/src/resolvers/mutations/verifySafe.ts index a4dc1b9b..d386b506 100644 --- a/src/resolvers/mutations/verifySafe.ts +++ b/src/resolvers/mutations/verifySafe.ts @@ -5,11 +5,7 @@ import { VerifiedSafe } from "../../api-db/client"; import { RpcGateway } from "../../circles/rpcGateway"; import { Environment } from "../../environment"; -export const verifySafe = async ( - parent: any, - args: MutationVerifySafeArgs, - context: Context -) => { +export const verifySafe = async (parent: any, args: MutationVerifySafeArgs, context: Context) => { // TODO: Usually only BIL is allowed to verify new people (see commented out code below) /* const callerInfo = await context.callerInfo; @@ -18,12 +14,11 @@ export const verifySafe = async ( throw new Error(`Not allowed`); } */ - let verifiedSafe: VerifiedSafe | null = - await Environment.readWriteApiDb.verifiedSafe.findUnique({ - where: { - safeAddress: args.safeAddress.toLowerCase(), - }, - }); + let verifiedSafe: VerifiedSafe | null = await Environment.readWriteApiDb.verifiedSafe.findUnique({ + where: { + safeAddress: args.safeAddress.toLowerCase(), + }, + }); if (verifiedSafe) { return { @@ -42,9 +37,7 @@ export const verifySafe = async ( }); if (!bilOrga) { - throw new Error( - `Couldn't find an organisation with safe address ${Environment.operatorOrganisationAddress}` - ); + throw new Error(`Couldn't find an organisation with safe address ${Environment.operatorOrganisationAddress}`); } const swapEoa = RpcGateway.get().eth.accounts.create(); @@ -63,7 +56,8 @@ export const verifySafe = async ( if (bilOrga.circlesAddress) { await Environment.indexDb.query( - `call publish_event('follow_trust', '{"to":"${bilOrga.circlesAddress.toLowerCase()}"}');`); + `call publish_event('follow_trust', '{"to":"${bilOrga.circlesAddress.toLowerCase()}"}');` + ); } return { @@ -71,38 +65,32 @@ export const verifySafe = async ( }; }; -export const revokeSafeVerification = async ( - parent: any, - args: MutationVerifySafeArgs, - context: Context -) => { +export const revokeSafeVerification = async (parent: any, args: MutationVerifySafeArgs, context: Context) => { const callerInfo = await context.callerInfo; const isBilMember = await isBILMember(callerInfo?.profile?.circlesAddress); if (!isBilMember || !callerInfo?.profile) { throw new Error(`Not allowed`); } - let verifiedSafe: VerifiedSafe | null = - await Environment.readWriteApiDb.verifiedSafe.findUnique({ - where: { - safeAddress: args.safeAddress.toLowerCase(), - }, - }); + let verifiedSafe: VerifiedSafe | null = await Environment.readWriteApiDb.verifiedSafe.findUnique({ + where: { + safeAddress: args.safeAddress.toLowerCase(), + }, + }); if (!verifiedSafe) { throw new Error(`Safe ${args.safeAddress} is not verified.`); } - const revokeVerification = - await Environment.readWriteApiDb.verifiedSafe.update({ - where: { - safeAddress: verifiedSafe.safeAddress, - }, - data: { - revokedAt: new Date(), - revokedByProfileId: callerInfo.profile.id, - }, - }); + const revokeVerification = await Environment.readWriteApiDb.verifiedSafe.update({ + where: { + safeAddress: verifiedSafe.safeAddress, + }, + data: { + revokedAt: new Date(), + revokedByProfileId: callerInfo.profile.id, + }, + }); return { success: true, diff --git a/src/resolvers/queries/sessionInfo.ts b/src/resolvers/queries/sessionInfo.ts index ac5c4be9..b62db7b2 100644 --- a/src/resolvers/queries/sessionInfo.ts +++ b/src/resolvers/queries/sessionInfo.ts @@ -1,105 +1,103 @@ -import {Context} from "../../context"; -import {CapabilityType, SessionInfo} from "../../types"; -import {ProfileLoader} from "../../querySources/profileLoader"; -import {isBALIMember, isBILMember, isHumanodeVerified, isOrgaOwner} from "../../utils/canAccess"; -import {Environment} from "../../environment"; - -export async function getCapabilities(callerInfo:any) { - const capabilities = []; - - const checkPromises = await Promise.all([ - await isBILMember(callerInfo?.profile?.circlesAddress), - await isBALIMember(callerInfo?.profile?.circlesAddress), - await isHumanodeVerified(callerInfo?.profile?.circlesAddress), - await isOrgaOwner(callerInfo?.profile?.circlesAddress), - ]); - - const isBilMember = checkPromises[0]; - const isBaliMember = checkPromises[1]; - const humanodeVerified = checkPromises[2]; - const isOrgaAdmin = checkPromises[3]; - - if (isBilMember) { - capabilities.push({ - type: CapabilityType.Verify - }); - capabilities.push({ - type: CapabilityType.Translate - }); - } +import { Context } from "../../context"; +import { CapabilityType, SessionInfo } from "../../types"; +import { ProfileLoader } from "../../querySources/profileLoader"; +import { isTranslator, isBALIMember, isBILMember, isHumanodeVerified, isOrgaOwner } from "../../utils/canAccess"; +import { Environment } from "../../environment"; + +export async function getCapabilities(callerInfo: any) { + const capabilities = []; + + const checkPromises = await Promise.all([ + await isBILMember(callerInfo?.profile?.circlesAddress), + await isBALIMember(callerInfo?.profile?.circlesAddress), + await isHumanodeVerified(callerInfo?.profile?.circlesAddress), + await isOrgaOwner(callerInfo?.profile?.circlesAddress), + await isTranslator(callerInfo?.profile?.circlesAddress), + ]); + + const isBilMember = checkPromises[0]; + const isBaliMember = checkPromises[1]; + const humanodeVerified = checkPromises[2]; + const isOrgaAdmin = checkPromises[3]; + const canTranslate = checkPromises[4]; + + if (isBilMember) { + capabilities.push({ + type: CapabilityType.Verify, + }); + } + if (canTranslate) { + capabilities.push({ + type: CapabilityType.Translate, + }); + } - if (!isBilMember && isBaliMember) { - capabilities.push({ - type: CapabilityType.Translate - }); - } + capabilities.push({ + type: CapabilityType.PreviewFeatures, + }); + if (humanodeVerified) { capabilities.push({ - type: CapabilityType.PreviewFeatures + type: CapabilityType.VerifiedByHumanode, }); + } - if (humanodeVerified) { - capabilities.push({ - type: CapabilityType.VerifiedByHumanode - }); - } - - if (isOrgaAdmin) { - capabilities.push({ - type: CapabilityType.Invite - }); - } + if (isOrgaAdmin) { + capabilities.push({ + type: CapabilityType.Invite, + }); + } - return capabilities; + return capabilities; } -export const sessionInfo = async (parent:any, args:any, context:Context) : Promise => { - try { - const callerInfo = await context.callerInfo; - const capabilities = await getCapabilities(callerInfo); - - - const invitation = await Environment.readWriteApiDb.invitation.findFirst({ - where: { - redeemedByProfileId: callerInfo?.profile?.id - }, - include: { - createdBy: true - } - }); - - const useShortSignup: boolean | undefined = !!invitation && invitation.createdBy.circlesAddress == Environment.gorilloOrgaSafeAddress; - return { - isLoggedOn: true, - hasProfile: !!callerInfo?.profile, - profileId: callerInfo?.profile?.id, - profile: callerInfo?.profile ? ProfileLoader.withDisplayCurrency(callerInfo.profile) : null, - capabilities: capabilities, - useShortSignup: useShortSignup - } - } catch(e) { - context.log(JSON.stringify(e)); +export const sessionInfo = async (parent: any, args: any, context: Context): Promise => { + try { + const callerInfo = await context.callerInfo; + const capabilities = await getCapabilities(callerInfo); + + const invitation = await Environment.readWriteApiDb.invitation.findFirst({ + where: { + redeemedByProfileId: callerInfo?.profile?.id, + }, + include: { + createdBy: true, + }, + }); - // When the session is invalid, make sure that the user doesn't keep the cookie - const expires = new Date(); - /// See https://www.npmjs.com/package/apollo-server-plugin-http-headers for the magic that happens below ;) - context.setCookies.push({ - name: `session_${Environment.appId.replace(/\./g, "_")}`, - value: "no-session", - options: { - domain: Environment.externalDomain, - httpOnly: true, - path: "/", - sameSite: Environment.isLocalDebugEnvironment ? "Strict" : "None", - secure: !Environment.isLocalDebugEnvironment, - expires: expires - } - }); + const useShortSignup: boolean | undefined = + !!invitation && invitation.createdBy.circlesAddress == Environment.gorilloOrgaSafeAddress; + return { + isLoggedOn: true, + hasProfile: !!callerInfo?.profile, + profileId: callerInfo?.profile?.id, + profile: callerInfo?.profile ? ProfileLoader.withDisplayCurrency(callerInfo.profile) : null, + capabilities: capabilities, + useShortSignup: useShortSignup, + }; + } catch (e) { + context.log(JSON.stringify(e)); + + // When the session is invalid, make sure that the user doesn't keep the cookie + const expires = new Date(); + /// See https://www.npmjs.com/package/apollo-server-plugin-http-headers for the magic that happens below ;) + context.setCookies.push({ + name: `session_${Environment.appId.replace(/\./g, "_")}`, + value: "no-session", + options: { + domain: Environment.externalDomain, + httpOnly: true, + path: "/", + sameSite: Environment.isLocalDebugEnvironment ? "Strict" : "None", + secure: !Environment.isLocalDebugEnvironment, + expires: expires, + }, + }); - return { - isLoggedOn: false, - capabilities: [] - } - } -} + return { + isLoggedOn: false, + capabilities: [], + }; + } +}; diff --git a/src/utils/canAccess.ts b/src/utils/canAccess.ts index 2cb54111..9565eb40 100644 --- a/src/utils/canAccess.ts +++ b/src/utils/canAccess.ts @@ -1,33 +1,47 @@ -import {Context} from "../context"; -import {Environment} from "../environment"; +import { Context } from "../context"; +import { Environment } from "../environment"; - -export async function isHumanodeVerified(circlesAddress?:string|null) { - if (!circlesAddress) - return false; +export async function isHumanodeVerified(circlesAddress?: string | null) { + if (!circlesAddress) return false; const profile = await Environment.readWriteApiDb.humanodeVerifications.findFirst({ where: { - circlesAddress: circlesAddress - } + circlesAddress: circlesAddress, + }, }); return !!profile; } -export async function isBILMember(circlesAddress?:string|null) { - if (!circlesAddress) - return false; +export async function isBILMember(circlesAddress?: string | null) { + if (!circlesAddress) return false; const orga = await Environment.readonlyApiDb.profile.findFirst({ where: { circlesAddress: Environment.operatorOrganisationAddress, members: { some: { - memberAddress: circlesAddress - } - } - } + memberAddress: circlesAddress, + }, + }, + }, + }); + + return !!orga; +} + +export async function isTranslator(circlesAddress?: string | null) { + if (!circlesAddress) return false; + + const orga = await Environment.readonlyApiDb.profile.findFirst({ + where: { + circlesAddress: Environment.translatorOrganisationAddress, + members: { + some: { + memberAddress: circlesAddress, + }, + }, + }, }); return !!orga; @@ -37,39 +51,37 @@ export async function isBILMember(circlesAddress?:string|null) { * Checks if the given circlesAddress is an owner of any organization * @param circlesAddress */ -export async function isOrgaOwner(circlesAddress?:string|null) { - if (!circlesAddress) - return false; +export async function isOrgaOwner(circlesAddress?: string | null) { + if (!circlesAddress) return false; const orga = await Environment.readonlyApiDb.membership.findFirst({ where: { memberAddress: circlesAddress, - isAdmin: true - } + isAdmin: true, + }, }); return !!orga; } -export async function isBALIMember(circlesAddress?:string|null) { - if (!circlesAddress) - return false; +export async function isBALIMember(circlesAddress?: string | null) { + if (!circlesAddress) return false; const orga = await Environment.readonlyApiDb.profile.findFirst({ where: { circlesAddress: "0xdf5b1ea0aa4117770779fd46a7aa237c4dc0bdbd", members: { some: { - memberAddress: circlesAddress - } - } - } + memberAddress: circlesAddress, + }, + }, + }, }); return !!orga; } -export async function canAccess(context:Context, accessedSafeAddress:string) { +export async function canAccess(context: Context, accessedSafeAddress: string) { const callerInfo = await context.callerInfo; if (callerInfo?.profile?.circlesAddress == accessedSafeAddress) { return true; @@ -78,23 +90,23 @@ export async function canAccess(context:Context, accessedSafeAddress:string) { const requestedProfile = await Environment.readWriteApiDb.profile.findMany({ where: { circlesAddress: accessedSafeAddress, - type: "ORGANISATION" + type: "ORGANISATION", }, orderBy: { - id: "desc" + id: "desc", }, include: { members: true /* { where: { isAdmin: true } - }*/ - } + }*/, + }, }); const orgaProfile = requestedProfile.length > 0 ? requestedProfile[0] : undefined; if (orgaProfile) { - if (orgaProfile.members.find(o => o.memberAddress == callerInfo?.profile?.circlesAddress)) { + if (orgaProfile.members.find((o) => o.memberAddress == callerInfo?.profile?.circlesAddress)) { return true; } @@ -104,7 +116,7 @@ export async function canAccess(context:Context, accessedSafeAddress:string) { return false; } -export async function canAccessProfileId(context:Context, profileId:number) { +export async function canAccessProfileId(context: Context, profileId: number) { const callerInfo = await context.callerInfo; if (callerInfo?.profile?.id == profileId) { return callerInfo; @@ -113,23 +125,23 @@ export async function canAccessProfileId(context:Context, profileId:number) { const requestedProfile = await Environment.readWriteApiDb.profile.findMany({ where: { id: profileId, - type: "ORGANISATION" + type: "ORGANISATION", }, orderBy: { - id: "desc" + id: "desc", }, include: { members: true /* { where: { isAdmin: true } - }*/ - } + }*/, + }, }); const orgaProfile = requestedProfile.length > 0 ? requestedProfile[0] : undefined; if (orgaProfile) { - if (orgaProfile.members.find(o => o.memberAddress == callerInfo?.profile?.circlesAddress)) { + if (orgaProfile.members.find((o) => o.memberAddress == callerInfo?.profile?.circlesAddress)) { return callerInfo; }