mirror of
https://github.com/formbricks/formbricks.git
synced 2025-12-30 10:19:51 -06:00
refactor: Airtable & GS endpoints to use responses return objects (#1592)
This commit is contained in:
committed by
GitHub
parent
d6c9ce7c5b
commit
dd0f0ead39
@@ -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=
|
||||
|
||||
@@ -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.
|
||||
|
||||
|
||||
@@ -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;
|
||||
};
|
||||
|
||||
@@ -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),
|
||||
|
||||
@@ -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;
|
||||
};
|
||||
|
||||
@@ -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`);
|
||||
|
||||
@@ -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 });
|
||||
}
|
||||
|
||||
@@ -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");
|
||||
}
|
||||
|
||||
@@ -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() });
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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,
|
||||
},
|
||||
});
|
||||
|
||||
@@ -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",
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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",
|
||||
|
||||
Reference in New Issue
Block a user