refactor: Airtable & GS endpoints to use responses return objects (#1592)

This commit is contained in:
Dhruwang Jariwala
2023-11-09 15:31:49 +05:30
committed by GitHub
parent d6c9ce7c5b
commit dd0f0ead39
14 changed files with 62 additions and 76 deletions

View File

@@ -122,7 +122,7 @@ GOOGLE_SHEETS_CLIENT_SECRET=
GOOGLE_SHEETS_REDIRECT_URL=
# Oauth credentials for Airtable integration
AIR_TABLE_CLIENT_ID=
AIRTABLE_CLIENT_ID=
# Enterprise License Key
ENTERPRISE_LICENSE_KEY=

View File

@@ -160,8 +160,8 @@ Enabling the Airtable Integration in a self-hosted environment requires creating
### By now, your environment variables should include the below ones:
- `AIR_TABLE_CLIENT_ID`
- `AIR_TABLE_REDIRECT_URL`
- `AIRTABLE_CLIENT_ID`
- `AIRTABLE_REDIRECT_URL`
Voila! You have successfully enabled the Airtable integration in your self-hosted Formbricks instance. Now you can follow the steps mentioned in the [Formbricks Cloud](#formbricks-cloud) section to link an Airtable with Formbricks.

View File

@@ -6,8 +6,8 @@ export const fetchTables = async (environmentId: string, baseId: string) => {
headers: { environmentId: environmentId },
cache: "no-store",
});
return res.json() as Promise<TIntegrationAirtableTables>;
const resJson = await res.json();
return resJson.data as Promise<TIntegrationAirtableTables>;
};
export const authorize = async (environmentId: string, apiHost: string): Promise<string> => {
@@ -21,6 +21,6 @@ export const authorize = async (environmentId: string, apiHost: string): Promise
throw new Error("Could not create response");
}
const resJSON = await res.json();
const authUrl = resJSON.authUrl;
const authUrl = resJSON.data.authUrl;
return authUrl;
};

View File

@@ -1,6 +1,6 @@
import AirtableWrapper from "@/app/(app)/environments/[environmentId]/integrations/airtable/components/AirtableWrapper";
import { getAirtableTables } from "@formbricks/lib/airtable/service";
import { AIR_TABLE_CLIENT_ID, WEBAPP_URL } from "@formbricks/lib/constants";
import { AIRTABLE_CLIENT_ID, WEBAPP_URL } from "@formbricks/lib/constants";
import { getEnvironment } from "@formbricks/lib/environment/service";
import { getIntegrations } from "@formbricks/lib/integration/service";
import { getSurveys } from "@formbricks/lib/survey/service";
@@ -9,7 +9,7 @@ import { TIntegrationAirtable } from "@formbricks/types/integration/airtable";
import GoBackButton from "@formbricks/ui/GoBackButton";
export default async function Airtable({ params }) {
const enabled = !!AIR_TABLE_CLIENT_ID;
const enabled = !!AIRTABLE_CLIENT_ID;
const [surveys, integrations, environment] = await Promise.all([
getSurveys(params.environmentId),
getIntegrations(params.environmentId),

View File

@@ -9,6 +9,6 @@ export const authorize = async (environmentId: string, apiHost: string): Promise
throw new Error("Could not create response");
}
const resJSON = await res.json();
const authUrl = resJSON.authUrl;
const authUrl = resJSON.data.authUrl;
return authUrl;
};

View File

@@ -1,10 +1,11 @@
import { prisma } from "@formbricks/database";
import { responses } from "@/app/lib/api/response";
import {
GOOGLE_SHEETS_CLIENT_ID,
WEBAPP_URL,
GOOGLE_SHEETS_CLIENT_SECRET,
GOOGLE_SHEETS_REDIRECT_URL,
} from "@formbricks/lib/constants";
import { createOrUpdateIntegration } from "@formbricks/lib/integration/service";
import { google } from "googleapis";
import { NextRequest, NextResponse } from "next/server";
@@ -15,19 +16,19 @@ export async function GET(req: NextRequest) {
const code = queryParams.get("code");
if (!environmentId) {
return NextResponse.json({ error: "Invalid environmentId" });
return responses.badRequestResponse("Invalid environmentId");
}
if (code && typeof code !== "string") {
return NextResponse.json({ message: "`code` must be a string" }, { status: 400 });
return responses.badRequestResponse("`code` must be a string");
}
const client_id = GOOGLE_SHEETS_CLIENT_ID;
const client_secret = GOOGLE_SHEETS_CLIENT_SECRET;
const redirect_uri = GOOGLE_SHEETS_REDIRECT_URL;
if (!client_id) return NextResponse.json({ Error: "Google client id is missing" }, { status: 400 });
if (!client_secret) return NextResponse.json({ Error: "Google client secret is missing" }, { status: 400 });
if (!redirect_uri) return NextResponse.json({ Error: "Google redirect url is missing" }, { status: 400 });
if (!client_id) return responses.internalServerErrorResponse("Google client id is missing");
if (!client_secret) return responses.internalServerErrorResponse("Google client secret is missing");
if (!redirect_uri) return responses.internalServerErrorResponse("Google redirect url is missing");
const oAuth2Client = new google.auth.OAuth2(client_id, client_secret, redirect_uri);
let key;
@@ -61,22 +62,7 @@ export async function GET(req: NextRequest) {
},
};
const result = await prisma.integration.upsert({
where: {
type_environmentId: {
environmentId,
type: "googleSheets",
},
},
update: {
...googleSheetIntegration,
environment: { connect: { id: environmentId } },
},
create: {
...googleSheetIntegration,
environment: { connect: { id: environmentId } },
},
});
const result = await createOrUpdateIntegration(environmentId, googleSheetIntegration);
if (result) {
return NextResponse.redirect(`${WEBAPP_URL}/environments/${environmentId}/integrations/google-sheets`);

View File

@@ -1,11 +1,12 @@
import { hasUserEnvironmentAccess } from "@formbricks/lib/environment/auth";
import { responses } from "@/app/lib/api/response";
import {
GOOGLE_SHEETS_CLIENT_ID,
GOOGLE_SHEETS_CLIENT_SECRET,
GOOGLE_SHEETS_REDIRECT_URL,
} from "@formbricks/lib/constants";
import { google } from "googleapis";
import { NextRequest, NextResponse } from "next/server";
import { NextRequest } from "next/server";
import { authOptions } from "@formbricks/lib/authOptions";
import { getServerSession } from "next-auth";
@@ -20,24 +21,24 @@ export async function GET(req: NextRequest) {
const session = await getServerSession(authOptions);
if (!environmentId) {
return NextResponse.json({ Error: "environmentId is missing" }, { status: 400 });
return responses.badRequestResponse("environmentId is missing");
}
if (!session) {
return NextResponse.json({ Error: "Invalid session" }, { status: 400 });
return responses.notAuthenticatedResponse();
}
const canUserAccessEnvironment = await hasUserEnvironmentAccess(session?.user.id, environmentId);
if (!canUserAccessEnvironment) {
return NextResponse.json({ Error: "You dont have access to environment" }, { status: 401 });
return responses.unauthorizedResponse();
}
const client_id = GOOGLE_SHEETS_CLIENT_ID;
const client_secret = GOOGLE_SHEETS_CLIENT_SECRET;
const redirect_uri = GOOGLE_SHEETS_REDIRECT_URL;
if (!client_id) return NextResponse.json({ Error: "Google client id is missing" }, { status: 400 });
if (!client_secret) return NextResponse.json({ Error: "Google client secret is missing" }, { status: 400 });
if (!redirect_uri) return NextResponse.json({ Error: "Google redirect url is missing" }, { status: 400 });
if (!client_id) return responses.internalServerErrorResponse("Google client id is missing");
if (!client_secret) return responses.internalServerErrorResponse("Google client secret is missing");
if (!redirect_uri) return responses.internalServerErrorResponse("Google redirect url is missing");
const oAuth2Client = new google.auth.OAuth2(client_id, client_secret, redirect_uri);
const authUrl = oAuth2Client.generateAuthUrl({
@@ -47,5 +48,5 @@ export async function GET(req: NextRequest) {
state: environmentId!,
});
return NextResponse.json({ authUrl }, { status: 200 });
return responses.successResponse({ authUrl });
}

View File

@@ -1,9 +1,10 @@
import { authOptions } from "@formbricks/lib/authOptions";
import { connectAirtable, fetchAirtableAuthToken } from "@formbricks/lib/airtable/service";
import { AIR_TABLE_CLIENT_ID, WEBAPP_URL } from "@formbricks/lib/constants";
import { AIRTABLE_CLIENT_ID, WEBAPP_URL } from "@formbricks/lib/constants";
import { hasUserEnvironmentAccess } from "@formbricks/lib/environment/auth";
import { getServerSession } from "next-auth";
import { NextRequest, NextResponse } from "next/server";
import { responses } from "@/app/lib/api/response";
import * as z from "zod";
async function getEmail(token: string) {
@@ -26,27 +27,27 @@ export async function GET(req: NextRequest) {
const session = await getServerSession(authOptions);
if (!environmentId) {
return NextResponse.json({ error: "Invalid environmentId" });
return responses.badRequestResponse("Invalid environmentId");
}
if (!session) {
return NextResponse.json({ Error: "Invalid session" }, { status: 400 });
return responses.notAuthenticatedResponse();
}
if (code && typeof code !== "string") {
return NextResponse.json({ message: "`code` must be a string" }, { status: 400 });
return responses.badRequestResponse("`code` must be a string");
}
const canUserAccessEnvironment = await hasUserEnvironmentAccess(session?.user.id, environmentId);
if (!canUserAccessEnvironment) {
return NextResponse.json({ Error: "You dont have access to environment" }, { status: 401 });
return responses.unauthorizedResponse();
}
const client_id = AIR_TABLE_CLIENT_ID;
const client_id = AIRTABLE_CLIENT_ID;
const redirect_uri = WEBAPP_URL + "/api/v1/integrations/airtable/callback";
const code_verifier = Buffer.from(environmentId + session.user.id + environmentId).toString("base64");
if (!client_id) return NextResponse.json({ Error: "Airtable client id is missing" }, { status: 400 });
if (!redirect_uri) return NextResponse.json({ Error: "Airtable redirect url is missing" }, { status: 400 });
if (!client_id) return responses.internalServerErrorResponse("Airtable client id is missing");
if (!redirect_uri) return responses.internalServerErrorResponse("Airtable redirect url is missing");
const formData = {
grant_type: "authorization_code",
@@ -59,7 +60,7 @@ export async function GET(req: NextRequest) {
try {
const key = await fetchAirtableAuthToken(formData);
if (!key) {
return NextResponse.json({ Error: "Failed to fetch Airtable auth token" }, { status: 500 });
return responses.notFoundResponse("airtable auth token", key);
}
const email = await getEmail(key.access_token);
@@ -71,8 +72,7 @@ export async function GET(req: NextRequest) {
return NextResponse.redirect(`${WEBAPP_URL}/environments/${environmentId}/integrations/airtable`);
} catch (error) {
console.error(error);
NextResponse.json({ Error: error }, { status: 500 });
responses.internalServerErrorResponse(error);
}
NextResponse.json({ Error: "unknown error occurred" }, { status: 400 });
responses.badRequestResponse("unknown error occurred");
}

View File

@@ -1,10 +1,11 @@
import { NextRequest, NextResponse } from "next/server";
import { NextRequest } from "next/server";
import { authOptions } from "@formbricks/lib/authOptions";
import { getServerSession } from "next-auth";
import { responses } from "@/app/lib/api/response";
import { hasUserEnvironmentAccess } from "@formbricks/lib/environment/auth";
import crypto from "crypto";
import { AIR_TABLE_CLIENT_ID, WEBAPP_URL } from "@formbricks/lib/constants";
import { AIRTABLE_CLIENT_ID, WEBAPP_URL } from "@formbricks/lib/constants";
const scope = `data.records:read data.records:write schema.bases:read schema.bases:write user.email:read`;
@@ -13,23 +14,22 @@ export async function GET(req: NextRequest) {
const session = await getServerSession(authOptions);
if (!environmentId) {
return NextResponse.json({ Error: "environmentId is missing" }, { status: 400 });
return responses.badRequestResponse("environmentId is missing");
}
if (!session) {
return NextResponse.json({ Error: "Invalid session" }, { status: 400 });
return responses.notAuthenticatedResponse();
}
const canUserAccessEnvironment = await hasUserEnvironmentAccess(session?.user.id, environmentId);
if (!canUserAccessEnvironment) {
return NextResponse.json({ Error: "You dont have access to environment" }, { status: 401 });
return responses.unauthorizedResponse();
}
const client_id = AIR_TABLE_CLIENT_ID;
const client_id = AIRTABLE_CLIENT_ID;
const redirect_uri = WEBAPP_URL + "/api/v1/integrations/airtable/callback";
if (!client_id) return NextResponse.json({ Error: "Airtable client id is missing" }, { status: 400 });
if (!redirect_uri) return NextResponse.json({ Error: "Airtable redirect url is missing" }, { status: 400 });
if (!client_id) return responses.internalServerErrorResponse("Airtable client id is missing");
if (!redirect_uri) return responses.internalServerErrorResponse("Airtable redirect url is missing");
const codeVerifier = Buffer.from(environmentId + session.user.id + environmentId).toString("base64");
const codeChallengeMethod = "S256";
@@ -51,5 +51,5 @@ export async function GET(req: NextRequest) {
authUrl.searchParams.append("code_challenge_method", codeChallengeMethod);
authUrl.searchParams.append("code_challenge", codeChallenge);
return NextResponse.json({ authUrl: authUrl.toString() }, { status: 200 });
return responses.successResponse({ authUrl: authUrl.toString() });
}

View File

@@ -4,7 +4,8 @@ import { hasUserEnvironmentAccess } from "@formbricks/lib/environment/auth";
import { getIntegrationByType } from "@formbricks/lib/integration/service";
import { TIntegrationAirtable } from "@formbricks/types/integration/airtable";
import { getServerSession } from "next-auth";
import { NextRequest, NextResponse } from "next/server";
import { NextRequest } from "next/server";
import { responses } from "@/app/lib/api/response";
import * as z from "zod";
export async function GET(req: NextRequest) {
@@ -15,30 +16,28 @@ export async function GET(req: NextRequest) {
const baseId = z.string().safeParse(queryParams.get("baseId"));
if (!baseId.success) {
return NextResponse.json({ Error: "Base Id is Required" }, { status: 400 });
return responses.missingFieldResponse("Base Id is Required");
}
if (!session) {
return NextResponse.json({ Error: "Invalid session" }, { status: 400 });
return responses.notAuthenticatedResponse();
}
if (!environmentId) {
return NextResponse.json({ Error: "environmentId is missing" }, { status: 400 });
return responses.badRequestResponse("environmentId is missing");
}
const canUserAccessEnvironment = await hasUserEnvironmentAccess(session?.user.id, environmentId);
if (!canUserAccessEnvironment || !environmentId) {
return NextResponse.json({ Error: "You dont have access to environment" }, { status: 401 });
return responses.unauthorizedResponse();
}
const integration = (await getIntegrationByType(environmentId, "airtable")) as TIntegrationAirtable;
console.log(integration);
if (!integration) {
return NextResponse.json({ Error: "integration not found" }, { status: 401 });
return responses.notFoundResponse("Integration not found", environmentId);
}
const tables = await getTables(integration.config.key, baseId.data);
return NextResponse.json(tables, { status: 200 });
return responses.successResponse(tables);
}

View File

@@ -54,7 +54,7 @@ export const env = createEnv({
GOOGLE_SHEETS_CLIENT_ID: z.string().optional(),
GOOGLE_SHEETS_CLIENT_SECRET: z.string().optional(),
GOOGLE_SHEETS_REDIRECT_URL: z.string().optional(),
AIR_TABLE_CLIENT_ID: z.string().optional(),
AIRTABLE_CLIENT_ID: z.string().optional(),
AWS_ACCESS_KEY: z.string().optional(),
AWS_SECRET_KEY: z.string().optional(),
S3_ACCESS_KEY: z.string().optional(),
@@ -139,7 +139,7 @@ export const env = createEnv({
AZUREAD_CLIENT_ID: process.env.AZUREAD_CLIENT_ID,
AZUREAD_CLIENT_SECRET: process.env.AZUREAD_CLIENT_SECRET,
AZUREAD_TENANT_ID: process.env.AZUREAD_TENANT_ID,
AIR_TABLE_CLIENT_ID: process.env.AIR_TABLE_CLIENT_ID,
AIRTABLE_CLIENT_ID: process.env.AIRTABLE_CLIENT_ID,
ENTERPRISE_LICENSE_KEY: process.env.ENTERPRISE_LICENSE_KEY,
},
});

View File

@@ -13,7 +13,7 @@ import {
ZIntegrationAirtableTokenSchema,
} from "@formbricks/types/integration/airtable";
import { Prisma } from "@prisma/client";
import { AIR_TABLE_CLIENT_ID } from "../constants";
import { AIRTABLE_CLIENT_ID } from "../constants";
import { createOrUpdateIntegration, deleteIntegration, getIntegrationByType } from "../integration/service";
interface ConnectAirtableOptions {
@@ -122,7 +122,7 @@ export const getAirtableToken = async (environmentId: string) => {
const currentDate = new Date();
if (currentDate >= expiryDate) {
const client_id = AIR_TABLE_CLIENT_ID;
const client_id = AIRTABLE_CLIENT_ID;
const newToken = await fetchAirtableAuthToken({
grant_type: "refresh_token",

View File

@@ -47,7 +47,7 @@ export const GOOGLE_SHEETS_CLIENT_ID = process.env.GOOGLE_SHEETS_CLIENT_ID;
export const GOOGLE_SHEETS_CLIENT_SECRET = process.env.GOOGLE_SHEETS_CLIENT_SECRET;
export const GOOGLE_SHEETS_REDIRECT_URL = process.env.GOOGLE_SHEETS_REDIRECT_URL;
export const AIR_TABLE_CLIENT_ID = process.env.AIR_TABLE_CLIENT_ID;
export const AIRTABLE_CLIENT_ID = process.env.AIRTABLE_CLIENT_ID;
export const SMTP_HOST = process.env.SMTP_HOST;
export const SMTP_PORT = process.env.SMTP_PORT;

View File

@@ -112,7 +112,7 @@
"TELEMETRY_DISABLED",
"VERCEL_URL",
"WEBAPP_URL",
"AIR_TABLE_CLIENT_ID",
"AIRTABLE_CLIENT_ID",
"AWS_ACCESS_KEY",
"AWS_SECRET_KEY",
"S3_ACCESS_KEY",