Compare commits

...

41 Commits

Author SHA1 Message Date
Nuno Pato
8ff58d7f23 Merge pull request #1330 from nhost/changeset-release/main
chore: update versions
2022-12-05 15:22:02 -01:00
github-actions[bot]
8dd1c7415b chore: update versions 2022-12-05 15:56:54 +00:00
Nuno Pato
ebd2749e38 Merge pull request #1329 from nhost/fix/hasura-duplicate-slug
fix(dashboard): use correct Hasura slug
2022-12-05 14:55:28 -01:00
Szilárd Dóró
80b604adda fix(dashboard): use correct Hasura slug 2022-12-05 16:35:35 +01:00
Nuno Pato
9d73050792 Merge pull request #1322 from nhost/changeset-release/main
chore: update versions
2022-12-05 14:20:47 -01:00
github-actions[bot]
91a1a41f5d chore: update versions 2022-12-05 14:41:11 +00:00
Nuno Pato
22e9c27c81 Merge pull request #1328 from nhost/fix/graphiql-editor
fix(dashboard): prevent error on GraphQL page
2022-12-05 13:39:28 -01:00
Szilárd Dóró
2d2beb53d2 fix(dashboard): prevent error on GraphQL page 2022-12-05 15:26:37 +01:00
Pilou
b403b0d6a0 Merge pull request #1327 from nhost/ci/unambiguous-git-log
chore: don't use PAT in renovate post PR
2022-12-05 14:21:43 +01:00
Pierre-Louis Mercereau
4dbac55cb4 chore: don't use PAT in renovate post PR 2022-12-05 14:20:56 +01:00
Pilou
c6e31ac741 Merge pull request #1324 from nhost/renovate/xstate-vue-2.x
fix(deps): update dependency @xstate/vue to v2
2022-12-05 13:06:56 +01:00
Pilou
0d3e8b3992 Merge pull request #1325 from nhost/ci/unambiguous-git-log
chore(gh-actions): `git log` unabiguously
2022-12-05 12:58:15 +01:00
Pierre-Louis Mercereau
b2afd14d61 chore(gh-actions): git log unabiguously 2022-12-05 12:57:46 +01:00
renovate[bot]
f28f28b6ee fix(deps): update dependency @xstate/vue to v2 2022-12-05 11:52:06 +00:00
Pilou
834b959271 Merge pull request #1323 from nhost/renovate/vueuse-core-9.x
fix(deps): update dependency @vueuse/core to v9
2022-12-05 12:44:43 +01:00
renovate[bot]
4dbc9ccc87 fix(deps): update dependency @vueuse/core to v9 2022-12-05 11:23:06 +00:00
Nuno Pato
1666ca2ec5 Merge pull request #1250 from nhost/chore/deprecate-old-dns-name
chore(dashboard): deprecate old DNS name
2022-12-05 10:10:37 -01:00
Pilou
346791d4d5 Merge pull request #1321 from nhost/renovate/pnpm-find-workspace-dir-5.x
fix(deps): update dependency @pnpm/find-workspace-dir to v5
2022-12-05 11:55:33 +01:00
Pierre-Louis Mercereau
94bdafe22f chore: adapt sync-versions to find-workspace-dir 5 2022-12-05 11:51:44 +01:00
renovate[bot]
33782e9d41 fix(deps): update dependency @pnpm/find-workspace-dir to v5 2022-12-05 10:46:45 +00:00
Johan Eliasson
ea02e1e104 Merge pull request #1311 from nhost/example-serverless-functions-stripe-webhooks
example(serverless functions): Stripe Webhooks
2022-12-05 11:39:36 +01:00
Johan Eliasson
98bf6e3792 Update examples/serverless-functions/functions/stripe-webhook/index.ts
Co-authored-by: Nuno Pato <nunopato@gmail.com>
2022-12-05 11:39:26 +01:00
Johan Eliasson
d9dcafd643 Update examples/serverless-functions/functions/stripe-webhook/index.ts
Co-authored-by: Nuno Pato <nunopato@gmail.com>
2022-12-05 11:39:20 +01:00
Johan Eliasson
4f3d97b5ad Merge pull request #1316 from nhost/elitan-patch-3
docs clarifications
2022-12-05 11:38:51 +01:00
Nuno Pato
d1801ceae9 dashboard: fix link 2022-12-05 09:12:40 -01:00
Johan Eliasson
1abc68992f Update users.mdx 2022-12-05 08:15:14 +01:00
Johan Eliasson
8ed965c669 keep migrations file here, otherwise nhost dev won't work 2022-12-03 14:44:22 +01:00
Johan Eliasson
c59f622feb fix 2022-12-03 13:48:40 +01:00
Johan Eliasson
9a30edd038 example 2022-12-03 13:47:42 +01:00
Szilárd Dóró
99ee9fd10d fix(dashboard): move Brazilian flag 2022-12-02 20:29:58 +01:00
Nuno Pato
9608a327c9 dashboard: add brazilian flag 2022-12-02 18:27:14 -01:00
Szilárd Dóró
492b83ef58 fix(dashboard): correct GraphQL URL 2022-12-02 20:25:11 +01:00
Szilárd Dóró
c9f88326b2 chore(dashboard): migrate app URLs to service URLs 2022-11-30 17:12:58 +01:00
Szilárd Dóró
ac8efcbdd5 chore(dashboard): add changeset 2022-11-30 16:13:30 +01:00
Szilárd Dóró
9bc346e8d4 fix(dashboard): minor layout fixes in provider alert 2022-11-30 16:12:11 +01:00
Nuno Pato
efed987d31 fix linter 2022-11-30 12:12:48 -01:00
Nuno Pato
bdab7da7d3 fix linter 2022-11-30 12:02:10 -01:00
Nuno Pato
c2d9993968 asd 2022-11-30 11:53:30 -01:00
Nuno Pato
508ba62207 update copy 2022-11-30 11:52:41 -01:00
Nuno Pato
a3318de06e incorporate minor changes from comments 2022-11-30 11:49:25 -01:00
Nuno Pato
fa9f7ca052 Deprecate old DNS name 2022-11-30 03:01:17 -01:00
60 changed files with 644 additions and 235 deletions

View File

@@ -21,7 +21,6 @@ jobs:
- uses: actions/checkout@v3
with:
fetch-depth: 0
token: ${{ secrets.GH_PAT }}
# * Install Node and dependencies. Package downloads will be cached for the next jobs.
- name: Install Node and dependencies
uses: ./.github/actions/install-dependencies
@@ -32,7 +31,7 @@ jobs:
- name: Determine bumps
id: bumps
run: |
LAST_NON_PR_SHA=$(git log --no-merges main origin/${{ github.head_ref }} --format=format:%h | head -2 | tail -1)
LAST_NON_PR_SHA=$(git log --no-merges main origin/${{ github.head_ref }} --format=format:%h -- | head -2 | tail -1)
echo "result<<EOF" >> $GITHUB_OUTPUT
pnpm recursive list --depth -1 --parseable \
--filter='!nhost-root' \

View File

@@ -1,5 +1,18 @@
# @nhost/dashboard
## 0.7.7
### Patch Changes
- 80b604ad: fix(dashboard): use correct Hasura slug
## 0.7.6
### Patch Changes
- 2d2beb53: fix(dashboard): prevent error on GraphQL page
- ac8efcbd: chore(dashboard): deprecate old DNS name
## 0.7.5
### Patch Changes

View File

@@ -1,6 +1,6 @@
{
"name": "@nhost/dashboard",
"version": "0.7.5",
"version": "0.7.7",
"private": true,
"scripts": {
"preinstall": "npx only-allow pnpm",
@@ -53,7 +53,7 @@
"cross-fetch": "^3.1.5",
"date-fns": "^2.29.3",
"generate-password": "^1.7.0",
"graphiql": "^2.1.0",
"graphiql": "^2.2.0",
"graphql": "^16.6.0",
"graphql-request": "^4.3.0",
"graphql-tag": "^2.12.6",

File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 19 KiB

View File

@@ -6,7 +6,7 @@ import ArrowSquareOutIcon from '@/ui/v2/icons/ArrowSquareOutIcon';
import Link from '@/ui/v2/Link';
import Text from '@/ui/v2/Text';
import { LOCAL_HASURA_URL } from '@/utils/env';
import { generateRemoteAppUrl } from '@/utils/helpers';
import { generateAppServiceUrl } from '@/utils/helpers';
import Image from 'next/image';
interface HasuraDataProps {
@@ -26,7 +26,11 @@ export function HasuraData({ close }: HasuraDataProps) {
const hasuraUrl =
process.env.NEXT_PUBLIC_ENV === 'dev'
? LOCAL_HASURA_URL
: generateRemoteAppUrl(currentApplication.subdomain);
: `${generateAppServiceUrl(
currentApplication?.subdomain,
currentApplication?.region.awsName,
'hasura',
)}/console`;
return (
<div className="mx-auto w-full max-w-md px-6 py-4 text-left">
@@ -60,7 +64,7 @@ export function HasuraData({ close }: HasuraDataProps) {
<div className="mt-6 grid grid-flow-row gap-2">
<Link
href={`${hasuraUrl}/console`}
href={hasuraUrl}
target="_blank"
rel="noreferrer noopener"
className="grid grid-flow-col items-center justify-center gap-1 rounded-[4px] bg-btn p-2 text-sm+ font-medium text-white hover:ring-2 motion-safe:transition-all"

View File

@@ -14,7 +14,7 @@ import List from '@/ui/v2/List';
import { ListItem } from '@/ui/v2/ListItem';
import Text from '@/ui/v2/Text';
import { LOCAL_HASURA_URL } from '@/utils/env';
import { generateRemoteAppUrl } from '@/utils/helpers';
import { generateAppServiceUrl, generateRemoteAppUrl } from '@/utils/helpers';
import { useGetAppInjectedVariablesQuery } from '@/utils/__generated__/graphql';
import { Fragment, useState } from 'react';
@@ -71,11 +71,6 @@ export default function SystemEnvironmentVariableSettings() {
});
}
const hasuraUrl =
process.env.NEXT_PUBLIC_ENV === 'dev'
? LOCAL_HASURA_URL
: generateRemoteAppUrl(currentApplication.subdomain);
const systemEnvironmentVariables = [
{
key: 'NHOST_BACKEND_URL',
@@ -83,7 +78,17 @@ export default function SystemEnvironmentVariableSettings() {
},
{ key: 'NHOST_SUBDOMAIN', value: currentApplication.subdomain },
{ key: 'NHOST_REGION', value: currentApplication.region.awsName },
{ key: 'NHOST_HASURA_URL', value: `${hasuraUrl}/console` },
{
key: 'NHOST_HASURA_URL',
value:
process.env.NEXT_PUBLIC_ENV === 'dev'
? LOCAL_HASURA_URL
: `${generateAppServiceUrl(
currentApplication.subdomain,
currentApplication.region.awsName,
'hasura',
)}/console`,
},
{ key: 'NHOST_AUTH_URL', value: appClient.auth.url },
{ key: 'NHOST_GRAPHQL_URL', value: appClient.graphql.url },
{ key: 'NHOST_STORAGE_URL', value: appClient.storage.url },

View File

@@ -11,7 +11,7 @@ import CopyIcon from '@/ui/v2/icons/CopyIcon';
import Input from '@/ui/v2/Input';
import InputAdornment from '@/ui/v2/InputAdornment';
import { copy } from '@/utils/copy';
import { generateRemoteAppUrl } from '@/utils/helpers';
import { generateAppServiceUrl } from '@/utils/helpers';
import { toastStyleProps } from '@/utils/settings/settingsConstants';
import { FormProvider, useForm } from 'react-hook-form';
import { toast } from 'react-hot-toast';
@@ -168,9 +168,11 @@ export default function AppleProviderSettings() {
<Input
name="redirectUrl"
id="redirectUrl"
defaultValue={`${generateRemoteAppUrl(
defaultValue={`${generateAppServiceUrl(
currentApplication.subdomain,
)}/v1/auth/signin/provider/apple/callback`}
currentApplication.region.awsName,
'auth',
)}/v1/signin/provider/apple/callback`}
className="col-span-2"
fullWidth
hideEmptyHelperText
@@ -185,9 +187,11 @@ export default function AppleProviderSettings() {
onClick={(e) => {
e.stopPropagation();
copy(
`${generateRemoteAppUrl(
`${generateAppServiceUrl(
currentApplication.subdomain,
)}/v1/auth/signin/provider/apple/callback`,
currentApplication.region.awsName,
'auth',
)}/v1/signin/provider/apple/callback`,
'Redirect URL',
);
}}

View File

@@ -13,7 +13,7 @@ import CopyIcon from '@/ui/v2/icons/CopyIcon';
import Input from '@/ui/v2/Input';
import InputAdornment from '@/ui/v2/InputAdornment';
import { copy } from '@/utils/copy';
import { generateRemoteAppUrl } from '@/utils/helpers';
import { generateAppServiceUrl } from '@/utils/helpers';
import { toastStyleProps } from '@/utils/settings/settingsConstants';
import { FormProvider, useForm } from 'react-hook-form';
import { toast } from 'react-hot-toast';
@@ -112,9 +112,11 @@ export default function DiscordProviderSettings() {
fullWidth
hideEmptyHelperText
label="Redirect URL"
defaultValue={`${generateRemoteAppUrl(
defaultValue={`${generateAppServiceUrl(
currentApplication.subdomain,
)}/v1/auth/signin/provider/discord/callback`}
currentApplication.region.awsName,
'auth',
)}/v1/signin/provider/discord/callback`}
disabled
endAdornment={
<InputAdornment position="end" className="absolute right-2">
@@ -125,9 +127,11 @@ export default function DiscordProviderSettings() {
onClick={(e) => {
e.stopPropagation();
copy(
`${generateRemoteAppUrl(
`${generateAppServiceUrl(
currentApplication.subdomain,
)}/v1/auth/signin/provider/discord/callback`,
currentApplication.region.awsName,
'auth',
)}/v1/signin/provider/discord/callback`,
'Redirect URL',
);
}}

View File

@@ -13,7 +13,7 @@ import CopyIcon from '@/ui/v2/icons/CopyIcon';
import Input from '@/ui/v2/Input';
import InputAdornment from '@/ui/v2/InputAdornment';
import { copy } from '@/utils/copy';
import { generateRemoteAppUrl } from '@/utils/helpers';
import { generateAppServiceUrl } from '@/utils/helpers';
import { toastStyleProps } from '@/utils/settings/settingsConstants';
import { FormProvider, useForm } from 'react-hook-form';
import { toast } from 'react-hot-toast';
@@ -112,9 +112,11 @@ export default function FacebookProviderSettings() {
fullWidth
hideEmptyHelperText
label="Redirect URL"
defaultValue={`${generateRemoteAppUrl(
defaultValue={`${generateAppServiceUrl(
currentApplication.subdomain,
)}/v1/auth/signin/provider/facebook/callback`}
currentApplication.region.awsName,
'auth',
)}/v1/signin/provider/facebook/callback`}
disabled
endAdornment={
<InputAdornment position="end" className="absolute right-2">
@@ -125,9 +127,11 @@ export default function FacebookProviderSettings() {
onClick={(e) => {
e.stopPropagation();
copy(
`${generateRemoteAppUrl(
`${generateAppServiceUrl(
currentApplication.subdomain,
)}/v1/auth/signin/provider/facebook/callback`,
currentApplication.region.awsName,
'auth',
)}/v1/signin/provider/facebook/callback`,
'Redirect URL',
);
}}

View File

@@ -13,7 +13,7 @@ import CopyIcon from '@/ui/v2/icons/CopyIcon';
import Input from '@/ui/v2/Input';
import InputAdornment from '@/ui/v2/InputAdornment';
import { copy } from '@/utils/copy';
import { generateRemoteAppUrl } from '@/utils/helpers';
import { generateAppServiceUrl } from '@/utils/helpers';
import { toastStyleProps } from '@/utils/settings/settingsConstants';
import { FormProvider, useForm } from 'react-hook-form';
import { toast } from 'react-hot-toast';
@@ -112,9 +112,11 @@ export default function GitHubProviderSettings() {
fullWidth
hideEmptyHelperText
label="Redirect URL"
defaultValue={`${generateRemoteAppUrl(
defaultValue={`${generateAppServiceUrl(
currentApplication.subdomain,
)}/v1/auth/signin/provider/github/callback`}
currentApplication.region.awsName,
'auth',
)}/v1/signin/provider/github/callback`}
disabled
endAdornment={
<InputAdornment position="end" className="absolute right-2">
@@ -125,9 +127,11 @@ export default function GitHubProviderSettings() {
onClick={(e) => {
e.stopPropagation();
copy(
`${generateRemoteAppUrl(
`${generateAppServiceUrl(
currentApplication.subdomain,
)}/v1/auth/signin/provider/github/callback`,
currentApplication.region.awsName,
'auth',
)}/v1/signin/provider/github/callback`,
'Redirect URL',
);
}}

View File

@@ -13,7 +13,7 @@ import CopyIcon from '@/ui/v2/icons/CopyIcon';
import Input from '@/ui/v2/Input';
import InputAdornment from '@/ui/v2/InputAdornment';
import { copy } from '@/utils/copy';
import { generateRemoteAppUrl } from '@/utils/helpers';
import { generateAppServiceUrl } from '@/utils/helpers';
import { toastStyleProps } from '@/utils/settings/settingsConstants';
import { FormProvider, useForm } from 'react-hook-form';
import { toast } from 'react-hot-toast';
@@ -112,9 +112,11 @@ export default function GoogleProviderSettings() {
fullWidth
hideEmptyHelperText
label="Redirect URL"
defaultValue={`${generateRemoteAppUrl(
defaultValue={`${generateAppServiceUrl(
currentApplication.subdomain,
)}/v1/auth/signin/provider/google/callback`}
currentApplication.region.awsName,
'auth',
)}/v1/signin/provider/google/callback`}
disabled
endAdornment={
<InputAdornment position="end" className="absolute right-2">
@@ -125,9 +127,11 @@ export default function GoogleProviderSettings() {
onClick={(e) => {
e.stopPropagation();
copy(
`${generateRemoteAppUrl(
`${generateAppServiceUrl(
currentApplication.subdomain,
)}/v1/auth/signin/provider/google/callback`,
currentApplication.region.awsName,
'auth',
)}/v1/signin/provider/google/callback`,
'Redirect URL',
);
}}

View File

@@ -13,7 +13,7 @@ import CopyIcon from '@/ui/v2/icons/CopyIcon';
import Input from '@/ui/v2/Input';
import InputAdornment from '@/ui/v2/InputAdornment';
import { copy } from '@/utils/copy';
import { generateRemoteAppUrl } from '@/utils/helpers';
import { generateAppServiceUrl } from '@/utils/helpers';
import { toastStyleProps } from '@/utils/settings/settingsConstants';
import { FormProvider, useForm } from 'react-hook-form';
import { toast } from 'react-hot-toast';
@@ -112,9 +112,11 @@ export default function LinkedInProviderSettings() {
fullWidth
hideEmptyHelperText
label="Redirect URL"
defaultValue={`${generateRemoteAppUrl(
defaultValue={`${generateAppServiceUrl(
currentApplication.subdomain,
)}/v1/auth/signin/provider/linkedin/callback`}
currentApplication.region.awsName,
'auth',
)}/v1/signin/provider/linkedin/callback`}
disabled
endAdornment={
<InputAdornment position="end" className="absolute right-2">
@@ -125,9 +127,11 @@ export default function LinkedInProviderSettings() {
onClick={(e) => {
e.stopPropagation();
copy(
`${generateRemoteAppUrl(
`${generateAppServiceUrl(
currentApplication.subdomain,
)}/v1/auth/signin/provider/linkedin/callback`,
currentApplication.region.awsName,
'auth',
)}/v1/signin/provider/linkedin/callback`,
'Redirect URL',
);
}}

View File

@@ -0,0 +1,87 @@
import { useDialog } from '@/components/common/DialogProvider';
import { useCurrentWorkspaceAndApplication } from '@/hooks/useCurrentWorkspaceAndApplication';
import { Alert } from '@/ui/Alert';
import Button from '@/ui/v2/Button';
import ArrowSquareOutIcon from '@/ui/v2/icons/ArrowSquareOutIcon';
import Link from '@/ui/v2/Link';
import Text from '@/ui/v2/Text';
import { toastStyleProps } from '@/utils/settings/settingsConstants';
import { useConfirmProvidersUpdatedMutation } from '@/utils/__generated__/graphql';
import { useState } from 'react';
import toast from 'react-hot-toast';
export default function ProvidersUpdatedAlert() {
const { currentApplication } = useCurrentWorkspaceAndApplication();
const { openAlertDialog } = useDialog();
const [confirmed, setConfirmed] = useState(true);
const [confirmProvidersUpdated] = useConfirmProvidersUpdatedMutation({
variables: { id: currentApplication?.id },
});
async function handleSubmitConfirmation() {
const confirmProvidersUpdatedPromise = confirmProvidersUpdated();
await toast.promise(
confirmProvidersUpdatedPromise,
{
loading: 'Confirming...',
success: 'Your settings have been updated successfully.',
error: 'An error occurred while trying to confirm the message.',
},
toastStyleProps,
);
setConfirmed(false);
}
function handleOpenConfirmationDialog() {
openAlertDialog({
title: 'Confirm all providers updated?',
payload: (
<Text variant="subtitle1" component="span">
Please make sure to update all providers before continuing. Your
sign-in flows might break if you don&apos;t.
</Text>
),
props: {
onPrimaryAction: handleSubmitConfirmation,
},
});
}
if (!confirmed) {
return null;
}
return (
<Alert className="grid items-center grid-flow-row gap-2 p-4 place-items-center lg:grid-flow-col lg:place-content-between bg-amber-500">
<div className="grid grid-flow-row gap-1 text-left">
<Text className="font-semibold">
Please update the Redirect URL for all providers being used
</Text>
<Text className="text-sm+">
We are deprecating your project&apos;s old DNS name in favor of
individual DNS names for each service. Please make sure to update your
providers to use the new auth specific URL under <b>Redirect URL</b>{' '}
before the 1st of February 2023.{' '}
<Link
href="https://github.com/nhost/nhost/discussions/1319"
target="_blank"
rel="noopener noreferrer"
underline="hover"
className="font-medium"
>
Read the discussion here.
<ArrowSquareOutIcon className="w-4 h-4 ml-1" />
</Link>
</Text>
</div>
<Button variant="borderless" onClick={handleOpenConfirmationDialog}>
I have updated all Redirect URLs
</Button>
</Alert>
);
}

View File

@@ -0,0 +1 @@
export { default } from './ProvidersUpdatedAlert';

View File

@@ -13,7 +13,7 @@ import CopyIcon from '@/ui/v2/icons/CopyIcon';
import Input from '@/ui/v2/Input';
import InputAdornment from '@/ui/v2/InputAdornment';
import { copy } from '@/utils/copy';
import { generateRemoteAppUrl } from '@/utils/helpers';
import { generateAppServiceUrl } from '@/utils/helpers';
import { toastStyleProps } from '@/utils/settings/settingsConstants';
import { FormProvider, useForm } from 'react-hook-form';
import { toast } from 'react-hot-toast';
@@ -112,9 +112,11 @@ export default function SpotifyProviderSettings() {
fullWidth
hideEmptyHelperText
label="Redirect URL"
defaultValue={`${generateRemoteAppUrl(
defaultValue={`${generateAppServiceUrl(
currentApplication.subdomain,
)}/v1/auth/signin/provider/spotify/callback`}
currentApplication.region.awsName,
'auth',
)}/v1/signin/provider/spotify/callback`}
disabled
endAdornment={
<InputAdornment position="end" className="absolute right-2">
@@ -125,9 +127,11 @@ export default function SpotifyProviderSettings() {
onClick={(e) => {
e.stopPropagation();
copy(
`${generateRemoteAppUrl(
`${generateAppServiceUrl(
currentApplication.subdomain,
)}/v1/auth/signin/provider/spotify/callback`,
currentApplication.region.awsName,
'auth',
)}/v1/signin/provider/spotify/callback`,
'Redirect URL',
);
}}

View File

@@ -13,7 +13,7 @@ import CopyIcon from '@/ui/v2/icons/CopyIcon';
import Input from '@/ui/v2/Input';
import InputAdornment from '@/ui/v2/InputAdornment';
import { copy } from '@/utils/copy';
import { generateRemoteAppUrl } from '@/utils/helpers';
import { generateAppServiceUrl } from '@/utils/helpers';
import { toastStyleProps } from '@/utils/settings/settingsConstants';
import { FormProvider, useForm } from 'react-hook-form';
import { toast } from 'react-hot-toast';
@@ -112,9 +112,11 @@ export default function TwitchProviderSettings() {
fullWidth
hideEmptyHelperText
label="Redirect URL"
defaultValue={`${generateRemoteAppUrl(
defaultValue={`${generateAppServiceUrl(
currentApplication.subdomain,
)}/v1/auth/signin/provider/twitch/callback`}
currentApplication.region.awsName,
'auth',
)}/v1/signin/provider/twitch/callback`}
disabled
endAdornment={
<InputAdornment position="end" className="absolute right-2">
@@ -125,9 +127,11 @@ export default function TwitchProviderSettings() {
onClick={(e) => {
e.stopPropagation();
copy(
`${generateRemoteAppUrl(
`${generateAppServiceUrl(
currentApplication.subdomain,
)}/v1/auth/signin/provider/twitch/callback`,
currentApplication.region.awsName,
'auth',
)}/v1/signin/provider/twitch/callback`,
'Redirect URL',
);
}}

View File

@@ -11,7 +11,7 @@ import CopyIcon from '@/ui/v2/icons/CopyIcon';
import Input from '@/ui/v2/Input';
import InputAdornment from '@/ui/v2/InputAdornment';
import { copy } from '@/utils/copy';
import { generateRemoteAppUrl } from '@/utils/helpers';
import { generateAppServiceUrl } from '@/utils/helpers';
import { toastStyleProps } from '@/utils/settings/settingsConstants';
import { FormProvider, useForm } from 'react-hook-form';
import { toast } from 'react-hot-toast';
@@ -125,9 +125,11 @@ export default function TwitterProviderSettings() {
<Input
name="redirectUrl"
id="redirectUrl"
defaultValue={`${generateRemoteAppUrl(
defaultValue={`${generateAppServiceUrl(
currentApplication.subdomain,
)}/v1/auth/signin/provider/twitter/callback`}
currentApplication.region.awsName,
'auth',
)}/v1/signin/provider/twitter/callback`}
className="col-span-2"
fullWidth
hideEmptyHelperText
@@ -142,9 +144,11 @@ export default function TwitterProviderSettings() {
onClick={(e) => {
e.stopPropagation();
copy(
`${generateRemoteAppUrl(
`${generateAppServiceUrl(
currentApplication.subdomain,
)}/v1/auth/signin/provider/twitter/callback`,
currentApplication.region.awsName,
'auth',
)}/v1/signin/provider/twitter/callback`,
'Redirect URL',
);
}}

View File

@@ -13,7 +13,7 @@ import CopyIcon from '@/ui/v2/icons/CopyIcon';
import Input from '@/ui/v2/Input';
import InputAdornment from '@/ui/v2/InputAdornment';
import { copy } from '@/utils/copy';
import { generateRemoteAppUrl } from '@/utils/helpers';
import { generateAppServiceUrl } from '@/utils/helpers';
import { toastStyleProps } from '@/utils/settings/settingsConstants';
import { FormProvider, useForm } from 'react-hook-form';
import { toast } from 'react-hot-toast';
@@ -111,9 +111,11 @@ export default function WindowsLiveProviderSettings() {
fullWidth
hideEmptyHelperText
label="Redirect URL"
defaultValue={`${generateRemoteAppUrl(
defaultValue={`${generateAppServiceUrl(
currentApplication.subdomain,
)}/v1/auth/signin/provider/microsoft/callback`}
currentApplication.region.awsName,
'auth',
)}/v1/signin/provider/microsoft/callback`}
disabled
endAdornment={
<InputAdornment position="end" className="absolute right-2">
@@ -124,9 +126,11 @@ export default function WindowsLiveProviderSettings() {
onClick={(e) => {
e.stopPropagation();
copy(
`${generateRemoteAppUrl(
`${generateAppServiceUrl(
currentApplication.subdomain,
)}/v1/auth/signin/provider/microsoft/callback`,
currentApplication.region.awsName,
'auth',
)}/v1/signin/provider/microsoft/callback`,
'Redirect URL',
);
}}

View File

@@ -11,7 +11,7 @@ import CopyIcon from '@/ui/v2/icons/CopyIcon';
import Input from '@/ui/v2/Input';
import InputAdornment from '@/ui/v2/InputAdornment';
import { copy } from '@/utils/copy';
import { generateRemoteAppUrl } from '@/utils/helpers';
import { generateAppServiceUrl } from '@/utils/helpers';
import { toastStyleProps } from '@/utils/settings/settingsConstants';
import { FormProvider, useForm } from 'react-hook-form';
import { toast } from 'react-hot-toast';
@@ -163,9 +163,11 @@ export default function WorkOsProviderSettings() {
<Input
name="redirectUrl"
id="redirectUrl"
defaultValue={`${generateRemoteAppUrl(
defaultValue={`${generateAppServiceUrl(
currentApplication.subdomain,
)}/v1/auth/signin/provider/workos/callback`}
currentApplication.region.awsName,
'auth',
)}/v1/signin/provider/workos/callback`}
className="col-span-6"
fullWidth
hideEmptyHelperText
@@ -180,9 +182,11 @@ export default function WorkOsProviderSettings() {
onClick={(e) => {
e.stopPropagation();
copy(
`${generateRemoteAppUrl(
`${generateAppServiceUrl(
currentApplication.subdomain,
)}/v1/auth/signin/provider/workos/callback`,
currentApplication.region.awsName,
'auth',
)}/v1/signin/provider/workos/callback`,
'Redirect URL',
);
}}

View File

@@ -4,7 +4,7 @@ import { Modal } from '@/ui/Modal';
import Button from '@/ui/v2/Button';
import Input from '@/ui/v2/Input';
import Text from '@/ui/v2/Text';
import { generateRemoteAppUrl } from '@/utils/helpers';
import { generateAppServiceUrl } from '@/utils/helpers';
import { triggerToast } from '@/utils/toast';
import { useApolloClient } from '@apollo/client';
import axios from 'axios';
@@ -43,9 +43,11 @@ export function AddUserModal({ modalIsOpen, setModalIsOpen }: any) {
return;
}
const signUpUrl = `${generateRemoteAppUrl(
const signUpUrl = `${generateAppServiceUrl(
currentApplication?.subdomain,
)}/v1/auth/signup/email-password`;
currentApplication?.region.awsName,
'auth',
)}/v1/signup/email-password`;
try {
await axios.post(signUpUrl, {

View File

@@ -7,6 +7,7 @@ fragment GetAppByWorkspaceAndName on apps {
name
createdAt
isProvisioned
providersUpdated
githubRepository {
id
name

View File

@@ -0,0 +1,5 @@
mutation confirmProvidersUpdated($id: uuid!) {
updateApp(pk_columns: { id: $id }, _set: { providersUpdated: true }) {
id
}
}

View File

@@ -24,6 +24,7 @@ query getOneUser($userId: uuid!) {
createdAt
desiredState
nhostBaseFolder
providersUpdated
featureFlags {
description
id

View File

@@ -1,6 +1,6 @@
import useIsPlatform from '@/hooks/common/useIsPlatform';
import { useCurrentWorkspaceAndApplication } from '@/hooks/useCurrentWorkspaceAndApplication';
import { generateRemoteAppUrl } from '@/utils/helpers';
import { generateAppServiceUrl } from '@/utils/helpers';
import type { MutationOptions } from '@tanstack/react-query';
import { useMutation } from '@tanstack/react-query';
import { useRouter } from 'next/router';
@@ -38,7 +38,11 @@ export default function useCreateColumnMutation({
query: { dataSourceSlug, schemaSlug, tableSlug },
} = useRouter();
const { currentApplication } = useCurrentWorkspaceAndApplication();
const appUrl = generateRemoteAppUrl(currentApplication?.subdomain);
const appUrl = generateAppServiceUrl(
currentApplication?.subdomain,
currentApplication?.region.awsName,
'hasura',
);
const mutationFn = isPlatform ? createColumn : createColumnMigration;
const mutation = useMutation(

View File

@@ -1,5 +1,5 @@
import { useCurrentWorkspaceAndApplication } from '@/hooks/useCurrentWorkspaceAndApplication';
import { generateRemoteAppUrl } from '@/utils/helpers';
import { generateAppServiceUrl } from '@/utils/helpers';
import type { MutationOptions } from '@tanstack/react-query';
import { useMutation } from '@tanstack/react-query';
import { useRouter } from 'next/router';
@@ -40,7 +40,11 @@ export default function useCreateRecordMutation<TData extends object = {}>({
query: { dataSourceSlug, schemaSlug, tableSlug },
} = useRouter();
const { currentApplication } = useCurrentWorkspaceAndApplication();
const appUrl = generateRemoteAppUrl(currentApplication?.subdomain);
const appUrl = generateAppServiceUrl(
currentApplication?.subdomain,
currentApplication?.region.awsName,
'hasura',
);
const mutation = useMutation(
(variables) =>

View File

@@ -1,6 +1,6 @@
import useIsPlatform from '@/hooks/common/useIsPlatform';
import { useCurrentWorkspaceAndApplication } from '@/hooks/useCurrentWorkspaceAndApplication';
import { generateRemoteAppUrl } from '@/utils/helpers';
import { generateAppServiceUrl } from '@/utils/helpers';
import type { MutationOptions } from '@tanstack/react-query';
import { useMutation } from '@tanstack/react-query';
import { useRouter } from 'next/router';
@@ -36,7 +36,11 @@ export default function useCreateTableMutation({
} = useRouter();
const { currentApplication } = useCurrentWorkspaceAndApplication();
const appUrl = generateRemoteAppUrl(currentApplication?.subdomain);
const appUrl = generateAppServiceUrl(
currentApplication?.subdomain,
currentApplication?.region.awsName,
'hasura',
);
const mutationFn = isPlatform ? createTable : createTableMigration;
const mutation = useMutation(

View File

@@ -1,5 +1,5 @@
import { useCurrentWorkspaceAndApplication } from '@/hooks/useCurrentWorkspaceAndApplication';
import { generateRemoteAppUrl } from '@/utils/helpers';
import { generateAppServiceUrl } from '@/utils/helpers';
import type { QueryKey, UseQueryOptions } from '@tanstack/react-query';
import { useQuery } from '@tanstack/react-query';
import { useRouter } from 'next/router';
@@ -38,7 +38,11 @@ export default function useDatabaseQuery(
isReady,
} = useRouter();
const { currentApplication } = useCurrentWorkspaceAndApplication();
const appUrl = generateRemoteAppUrl(currentApplication?.subdomain);
const appUrl = generateAppServiceUrl(
currentApplication?.subdomain,
currentApplication?.region.awsName,
'hasura',
);
const query = useQuery<FetchDatabaseReturnType>(
queryKey,

View File

@@ -1,6 +1,6 @@
import useIsPlatform from '@/hooks/common/useIsPlatform';
import { useCurrentWorkspaceAndApplication } from '@/hooks/useCurrentWorkspaceAndApplication';
import { generateRemoteAppUrl } from '@/utils/helpers';
import { generateAppServiceUrl } from '@/utils/helpers';
import type { MutationOptions } from '@tanstack/react-query';
import { useMutation } from '@tanstack/react-query';
import { useRouter } from 'next/router';
@@ -39,7 +39,11 @@ export default function useDeleteColumnMutation({
query: { dataSourceSlug, schemaSlug, tableSlug },
} = useRouter();
const { currentApplication } = useCurrentWorkspaceAndApplication();
const appUrl = generateRemoteAppUrl(currentApplication?.subdomain);
const appUrl = generateAppServiceUrl(
currentApplication?.subdomain,
currentApplication?.region.awsName,
'hasura',
);
const mutationFn = isPlatform ? deleteColumn : deleteColumnMigration;
const mutation = useMutation(

View File

@@ -1,5 +1,5 @@
import { useCurrentWorkspaceAndApplication } from '@/hooks/useCurrentWorkspaceAndApplication';
import { generateRemoteAppUrl } from '@/utils/helpers';
import { generateAppServiceUrl } from '@/utils/helpers';
import type { MutationOptions } from '@tanstack/react-query';
import { useMutation } from '@tanstack/react-query';
import { useRouter } from 'next/router';
@@ -36,7 +36,11 @@ export default function useDeleteRecordMutation({
query: { dataSourceSlug, schemaSlug, tableSlug },
} = useRouter();
const { currentApplication } = useCurrentWorkspaceAndApplication();
const appUrl = generateRemoteAppUrl(currentApplication?.subdomain);
const appUrl = generateAppServiceUrl(
currentApplication?.subdomain,
currentApplication?.region.awsName,
'hasura',
);
const mutation = useMutation(
(variables) =>

View File

@@ -1,6 +1,6 @@
import useIsPlatform from '@/hooks/common/useIsPlatform';
import { useCurrentWorkspaceAndApplication } from '@/hooks/useCurrentWorkspaceAndApplication';
import { generateRemoteAppUrl } from '@/utils/helpers';
import { generateAppServiceUrl } from '@/utils/helpers';
import type { MutationOptions } from '@tanstack/react-query';
import { useMutation } from '@tanstack/react-query';
import { useRouter } from 'next/router';
@@ -34,7 +34,11 @@ export default function useDeleteTableMutation({
query: { dataSourceSlug },
} = useRouter();
const { currentApplication } = useCurrentWorkspaceAndApplication();
const appUrl = generateRemoteAppUrl(currentApplication?.subdomain);
const appUrl = generateAppServiceUrl(
currentApplication?.subdomain,
currentApplication?.region.awsName,
'hasura',
);
const mutationFn = isPlatform ? deleteTable : deleteTableMigration;
const mutation = useMutation(

View File

@@ -1,5 +1,5 @@
import { useCurrentWorkspaceAndApplication } from '@/hooks/useCurrentWorkspaceAndApplication';
import { generateRemoteAppUrl } from '@/utils/helpers';
import { generateAppServiceUrl } from '@/utils/helpers';
import type { QueryKey, UseQueryOptions } from '@tanstack/react-query';
import { useQuery } from '@tanstack/react-query';
import { useRouter } from 'next/router';
@@ -39,7 +39,11 @@ export default function useMetadataQuery(
isReady,
} = useRouter();
const { currentApplication } = useCurrentWorkspaceAndApplication();
const appUrl = generateRemoteAppUrl(currentApplication?.subdomain);
const appUrl = generateAppServiceUrl(
currentApplication?.subdomain,
currentApplication?.region.awsName,
'hasura',
);
const query = useQuery<FetchMetadataReturnType>(
queryKey,

View File

@@ -1,5 +1,5 @@
import { useCurrentWorkspaceAndApplication } from '@/hooks/useCurrentWorkspaceAndApplication';
import { generateRemoteAppUrl } from '@/utils/helpers';
import { generateAppServiceUrl } from '@/utils/helpers';
import type { QueryKey, UseQueryOptions } from '@tanstack/react-query';
import { useQuery } from '@tanstack/react-query';
import { useRouter } from 'next/router';
@@ -39,7 +39,11 @@ export default function useTableQuery(
isReady,
} = useRouter();
const { currentApplication } = useCurrentWorkspaceAndApplication();
const appUrl = generateRemoteAppUrl(currentApplication?.subdomain);
const appUrl = generateAppServiceUrl(
currentApplication?.subdomain,
currentApplication?.region.awsName,
'hasura',
);
return useQuery<FetchTableReturnType>(
queryKey,

View File

@@ -1,6 +1,6 @@
import useIsPlatform from '@/hooks/common/useIsPlatform';
import { useCurrentWorkspaceAndApplication } from '@/hooks/useCurrentWorkspaceAndApplication';
import { generateRemoteAppUrl } from '@/utils/helpers';
import { generateAppServiceUrl } from '@/utils/helpers';
import type { MutationOptions } from '@tanstack/react-query';
import { useMutation } from '@tanstack/react-query';
import { useRouter } from 'next/router';
@@ -34,7 +34,11 @@ export default function useTrackForeignKeyRelationMutation({
query: { dataSourceSlug },
} = useRouter();
const { currentApplication } = useCurrentWorkspaceAndApplication();
const appUrl = generateRemoteAppUrl(currentApplication?.subdomain);
const appUrl = generateAppServiceUrl(
currentApplication?.subdomain,
currentApplication?.region.awsName,
'hasura',
);
const mutationFn = isPlatform
? trackForeignKeyRelations
: trackForeignKeyRelationsMigration;

View File

@@ -1,6 +1,6 @@
import useIsPlatform from '@/hooks/common/useIsPlatform';
import { useCurrentWorkspaceAndApplication } from '@/hooks/useCurrentWorkspaceAndApplication';
import { generateRemoteAppUrl } from '@/utils/helpers';
import { generateAppServiceUrl } from '@/utils/helpers';
import type { MutationOptions } from '@tanstack/react-query';
import { useMutation } from '@tanstack/react-query';
import { useRouter } from 'next/router';
@@ -35,7 +35,11 @@ export default function useTrackTableMutation({
query: { dataSourceSlug, schemaSlug },
} = useRouter();
const { currentApplication } = useCurrentWorkspaceAndApplication();
const appUrl = generateRemoteAppUrl(currentApplication?.subdomain);
const appUrl = generateAppServiceUrl(
currentApplication?.subdomain,
currentApplication?.region.awsName,
'hasura',
);
const mutationFn = isPlatform ? trackTable : trackTableMigration;
const mutation = useMutation(

View File

@@ -1,6 +1,6 @@
import useIsPlatform from '@/hooks/common/useIsPlatform';
import { useCurrentWorkspaceAndApplication } from '@/hooks/useCurrentWorkspaceAndApplication';
import { generateRemoteAppUrl } from '@/utils/helpers';
import { generateAppServiceUrl } from '@/utils/helpers';
import type { MutationOptions } from '@tanstack/react-query';
import { useMutation } from '@tanstack/react-query';
import { useRouter } from 'next/router';
@@ -39,7 +39,11 @@ export default function useUpdateColumnMutation({
query: { dataSourceSlug, schemaSlug, tableSlug },
} = useRouter();
const { currentApplication } = useCurrentWorkspaceAndApplication();
const appUrl = generateRemoteAppUrl(currentApplication?.subdomain);
const appUrl = generateAppServiceUrl(
currentApplication?.subdomain,
currentApplication?.region.awsName,
'hasura',
);
const mutationFn = isPlatform ? updateColumn : updateColumnMigration;
const mutation = useMutation(

View File

@@ -1,5 +1,5 @@
import { useCurrentWorkspaceAndApplication } from '@/hooks/useCurrentWorkspaceAndApplication';
import { generateRemoteAppUrl } from '@/utils/helpers';
import { generateAppServiceUrl } from '@/utils/helpers';
import type { MutationOptions } from '@tanstack/react-query';
import { useMutation } from '@tanstack/react-query';
import { useRouter } from 'next/router';
@@ -40,7 +40,11 @@ export default function useUpdateRecordMutation<TData extends object = {}>({
query: { dataSourceSlug, schemaSlug, tableSlug },
} = useRouter();
const { currentApplication } = useCurrentWorkspaceAndApplication();
const appUrl = generateRemoteAppUrl(currentApplication?.subdomain);
const appUrl = generateAppServiceUrl(
currentApplication?.subdomain,
currentApplication?.region.awsName,
'hasura',
);
const mutation = useMutation(
(variables) =>

View File

@@ -1,6 +1,6 @@
import useIsPlatform from '@/hooks/common/useIsPlatform';
import { useCurrentWorkspaceAndApplication } from '@/hooks/useCurrentWorkspaceAndApplication';
import { generateRemoteAppUrl } from '@/utils/helpers';
import { generateAppServiceUrl } from '@/utils/helpers';
import type { MutationOptions } from '@tanstack/react-query';
import { useMutation } from '@tanstack/react-query';
import { useRouter } from 'next/router';
@@ -35,7 +35,11 @@ export default function useUpdateTableMutation({
query: { dataSourceSlug, schemaSlug },
} = useRouter();
const { currentApplication } = useCurrentWorkspaceAndApplication();
const appUrl = generateRemoteAppUrl(currentApplication?.subdomain);
const appUrl = generateAppServiceUrl(
currentApplication?.subdomain,
currentApplication?.region.awsName,
'hasura',
);
const mutationFn = isPlatform ? updateTable : updateTableMigration;
const mutation = useMutation(

View File

@@ -1,12 +1,16 @@
import type { QueryError, QueryResult } from '@/types/data-browser';
import normalizeQueryError from '@/utils/dataBrowser/normalizeQueryError';
import { generateRemoteAppUrl } from '@/utils/helpers';
import { generateAppServiceUrl } from '@/utils/helpers';
export interface FetchProjectDatabaseSizeOptions {
/**
* Project subdomain.
*/
subdomain: string;
/**
* Project region.
*/
region: string;
/**
* Admin secret for the project.
*/
@@ -25,24 +29,26 @@ export interface FetchProjectDatabaseSizeReturnType {
*/
export default async function fetchProjectDatabaseSize({
subdomain,
region,
adminSecret,
}: FetchProjectDatabaseSizeOptions): Promise<FetchProjectDatabaseSizeReturnType> {
const appEndpoint = `${generateRemoteAppUrl(subdomain)}/v2/query`;
const response = await fetch(appEndpoint, {
method: 'POST',
headers: {
'x-hasura-admin-secret': adminSecret,
},
body: JSON.stringify({
type: 'run_sql',
args: {
sql: `SELECT pg_database_size('${
subdomain === 'localhost' ? 'postgres' : subdomain
}');`,
const response = await fetch(
`${generateAppServiceUrl(subdomain, region, 'hasura')}/v2/query`,
{
method: 'POST',
headers: {
'x-hasura-admin-secret': adminSecret,
},
}),
});
body: JSON.stringify({
type: 'run_sql',
args: {
sql: `SELECT pg_database_size('${
subdomain === 'localhost' ? 'postgres' : subdomain
}');`,
},
}),
},
);
const responseData: QueryResult<string[]> | QueryError =
await response.json();

View File

@@ -22,6 +22,7 @@ export default function useDatabaseSizeOfApplication(
() =>
fetchProjectDatabaseSize({
subdomain: currentApplication?.subdomain,
region: currentApplication?.region.awsName,
adminSecret: currentApplication?.hasuraGraphqlAdminSecret,
}),
{

View File

@@ -47,6 +47,7 @@ export function useCurrentWorkspaceAndApplication(): UseCurrentWorkspaceAndAppli
createdAt: new Date().toISOString(),
desiredState: ApplicationStatus.Live,
featureFlags: [],
providersUpdated: true,
};
setCurrentWorkspaceAndApplication({

View File

@@ -1,4 +1,4 @@
import { generateRemoteAppUrl } from '@/utils/helpers';
import { generateAppServiceUrl } from '@/utils/helpers';
import type {
Files_Order_By as FilesOrderBy,
GetFilesQuery,
@@ -66,9 +66,11 @@ export default function useFiles({
init: RequestInit,
size?: { width?: number; height?: number },
) => {
const fetchUrl = `${generateRemoteAppUrl(
const fetchUrl = `${generateAppServiceUrl(
currentApplication.subdomain,
)}/v1/storage/files/${file.id}`;
currentApplication.region.awsName,
'storage',
)}/v1/files/${file.id}`;
const fetchParams = new URLSearchParams();

View File

@@ -1,5 +1,5 @@
import { useCurrentWorkspaceAndApplication } from '@/hooks/useCurrentWorkspaceAndApplication';
import { generateRemoteAppUrl } from '@/utils/helpers';
import { generateAppServiceUrl } from '@/utils/helpers';
import { ApolloClient, HttpLink, InMemoryCache } from '@apollo/client';
import { useMemo } from 'react';
@@ -15,9 +15,11 @@ export function useRemoteApplicationGQLClient() {
new ApolloClient({
cache: new InMemoryCache(),
link: new HttpLink({
uri: `${generateRemoteAppUrl(
uri: `${generateAppServiceUrl(
currentApplication?.subdomain,
)}/v1/graphql`,
currentApplication?.region.awsName,
'graphql',
)}/v1`,
headers: {
'x-hasura-admin-secret':
process.env.NEXT_PUBLIC_ENV === 'dev'
@@ -28,6 +30,7 @@ export function useRemoteApplicationGQLClient() {
}),
[
currentApplication?.subdomain,
currentApplication?.region,
currentApplication?.hasuraGraphqlAdminSecret,
],
);

View File

@@ -13,7 +13,7 @@ import DelayedLoading from '@/ui/DelayedLoading';
import { Modal } from '@/ui/Modal';
import Status, { StatusEnum } from '@/ui/Status';
import { Text } from '@/ui/Text';
import { generateRemoteAppUrl } from '@/utils/helpers';
import { generateAppServiceUrl } from '@/utils/helpers';
import { useGetAppFunctionsMetadataQuery } from '@/utils/__generated__/graphql';
import { ChevronRightIcon } from '@heroicons/react/solid';
import clsx from 'clsx';
@@ -252,9 +252,11 @@ export default function FunctionsPage() {
<div className="text-center">
<Text size="tiny" color="greyscaleDark" className="font-medium">
Base URL for function endpoints is{' '}
{`${generateRemoteAppUrl(
{`${generateAppServiceUrl(
currentApplication.subdomain,
)}/v1/functions/`}
currentApplication.region.awsName,
'functions',
)}/v1`}
</Text>
</div>
</div>

View File

@@ -8,7 +8,7 @@ import ProjectLayout from '@/components/layout/ProjectLayout';
import { useCurrentWorkspaceAndApplication } from '@/hooks/useCurrentWorkspaceAndApplication';
import { useGetAllUserWorkspacesAndApplications } from '@/hooks/useGetAllUserWorkspacesAndApplications';
import { Text } from '@/ui/Text';
import { generateRemoteAppUrl, yieldFunction } from '@/utils/helpers';
import { generateAppServiceUrl, yieldFunction } from '@/utils/helpers';
import { useGetAppFunctionsMetadataQuery } from '@/utils/__generated__/graphql';
import Image from 'next/image';
import { useRouter } from 'next/router';
@@ -84,15 +84,19 @@ export default function FunctionDetailsPage() {
</Text>
<a
className="ml-2 text-xs font-medium text-greyscaleGrey"
href={`${generateRemoteAppUrl(
href={`${generateAppServiceUrl(
currentApplication.subdomain,
)}/v1/functions${currentFunction?.route}`}
currentApplication.region.awsName,
'functions',
)}/v1${currentFunction?.route}`}
target="_blank"
rel="noreferrer"
>
{`${generateRemoteAppUrl(
{`${generateAppServiceUrl(
currentApplication.subdomain,
)}/v1/functions${currentFunction?.route}`}
currentApplication.region.awsName,
'functions',
)}/v1${currentFunction?.route}`}
</a>
</div>
</div>

View File

@@ -9,7 +9,7 @@ import PlayIcon from '@/ui/v2/icons/PlayIcon';
import Option from '@/ui/v2/Option';
import Select from '@/ui/v2/Select';
import Tooltip from '@/ui/v2/Tooltip';
import { generateRemoteAppUrl } from '@/utils/helpers';
import { generateAppServiceUrl } from '@/utils/helpers';
import { triggerToast } from '@/utils/toast';
import {
DOC_EXPLORER_PLUGIN,
@@ -260,11 +260,15 @@ export default function GraphQLPage() {
return <LoadingScreen />;
}
const appUrl = generateRemoteAppUrl(currentApplication.subdomain);
const appUrl = generateAppServiceUrl(
currentApplication.subdomain,
currentApplication.region.awsName,
'graphql',
);
const subscriptionUrl = `${appUrl
.replace('https', 'wss')
.replace('http', 'ws')}/v1/graphql`;
.replace('http', 'ws')}/v1`;
const headers = {
'content-type': 'application/json',
@@ -273,7 +277,7 @@ export default function GraphQLPage() {
};
const fetcher = createGraphiQLFetcher({
url: `${appUrl}/v1/graphql`,
url: `${appUrl}/v1`,
headers,
wsClient: createClient({
url: subscriptionUrl,

View File

@@ -9,6 +9,7 @@ import GitHubProviderSettings from '@/components/settings/signInMethods/GitHubPr
import GoogleProviderSettings from '@/components/settings/signInMethods/GoogleProviderSettings';
import LinkedInProviderSettings from '@/components/settings/signInMethods/LinkedInProviderSettings';
import MagicLinkSettings from '@/components/settings/signInMethods/MagicLinkSettings';
import ProvidersUpdatedAlert from '@/components/settings/signInMethods/ProvidersUpdatedAlert';
import SMSSettings from '@/components/settings/signInMethods/SMSSettings';
import SpotifyProviderSettings from '@/components/settings/signInMethods/SpotifyProviderSettings';
import TwitchProviderSettings from '@/components/settings/signInMethods/TwitchProviderSettings';
@@ -55,6 +56,7 @@ export default function SettingsSignInMethodsPage() {
<WebAuthnSettings />
<AnonymousSignInSettings />
<SMSSettings />
{!currentApplication.providersUpdated && <ProvidersUpdatedAlert />}
<AppleProviderSettings />
<DiscordProviderSettings />
<FacebookProviderSettings />

View File

@@ -3,7 +3,7 @@ import RetryableErrorBoundary from '@/components/common/RetryableErrorBoundary';
import FilesDataGrid from '@/components/files/FilesDataGrid';
import ProjectLayout from '@/components/layout/ProjectLayout';
import { useCurrentWorkspaceAndApplication } from '@/hooks/useCurrentWorkspaceAndApplication';
import { generateRemoteAppUrl } from '@/utils/helpers';
import { generateAppServiceUrl } from '@/utils/helpers';
import { NhostApolloProvider } from '@nhost/react-apollo';
import type { ReactElement } from 'react';
@@ -16,9 +16,11 @@ export default function StoragePage() {
return (
<NhostApolloProvider
graphqlUrl={`${generateRemoteAppUrl(
currentApplication?.subdomain,
)}/v1/graphql`}
graphqlUrl={`${generateAppServiceUrl(
currentApplication.subdomain,
currentApplication.region.awsName,
'graphql',
)}/v1`}
fetchPolicy="cache-first"
headers={{
'x-hasura-admin-secret':

View File

@@ -20,7 +20,7 @@ import Option from '@/ui/v2/Option';
import Select from '@/ui/v2/Select';
import Text from '@/ui/v2/Text';
import { copy } from '@/utils/copy';
import { generateRemoteAppUrl } from '@/utils/helpers';
import { generateAppServiceUrl } from '@/utils/helpers';
import { triggerToast } from '@/utils/toast';
import type {
GetRemoteAppUserAuthRolesFragment,
@@ -629,9 +629,11 @@ export default function UserDetailsByIdPage() {
return (
<NhostApolloProvider
graphqlUrl={`${generateRemoteAppUrl(
graphqlUrl={`${generateAppServiceUrl(
currentApplication.subdomain,
)}/v1/graphql`}
currentApplication.region.awsName,
'graphql',
)}/v1`}
fetchPolicy="cache-first"
headers={{
'x-hasura-admin-secret':

View File

@@ -3,7 +3,7 @@ import Container from '@/components/layout/Container';
import ProjectLayout from '@/components/layout/ProjectLayout';
import UsersList from '@/components/users/UsersList';
import { useCurrentWorkspaceAndApplication } from '@/hooks/useCurrentWorkspaceAndApplication';
import { generateRemoteAppUrl } from '@/utils/helpers';
import { generateAppServiceUrl } from '@/utils/helpers';
import { NhostApolloProvider } from '@nhost/react-apollo';
import type { ReactElement } from 'react';
@@ -16,9 +16,11 @@ export default function UsersPage() {
return (
<NhostApolloProvider
graphqlUrl={`${generateRemoteAppUrl(
graphqlUrl={`${generateAppServiceUrl(
currentApplication.subdomain,
)}/v1/graphql`}
currentApplication.region.awsName,
'graphql',
)}/v1`}
fetchPolicy="cache-first"
headers={{
'x-hasura-admin-secret':

View File

@@ -76,6 +76,7 @@ export type Application = {
desiredState: DesiredState;
nhostBaseFolder?: string;
featureFlags: FeatureFlag[];
providersUpdated: boolean;
};
export type CustomClaim = {

View File

@@ -884,6 +884,7 @@ export type Apps = {
postgresSchemaMigrationUser?: Maybe<Scalars['String']>;
postgresUser?: Maybe<Scalars['String']>;
postgresVersion: Scalars['String'];
providersUpdated?: Maybe<Scalars['Boolean']>;
/** An object relationship */
region: Regions;
regionId: Scalars['uuid'];
@@ -1262,6 +1263,7 @@ export type Apps_Bool_Exp = {
postgresSchemaMigrationUser?: InputMaybe<String_Comparison_Exp>;
postgresUser?: InputMaybe<String_Comparison_Exp>;
postgresVersion?: InputMaybe<String_Comparison_Exp>;
providersUpdated?: InputMaybe<Boolean_Comparison_Exp>;
region?: InputMaybe<Regions_Bool_Exp>;
regionId?: InputMaybe<Uuid_Comparison_Exp>;
repositoryProductionBranch?: InputMaybe<String_Comparison_Exp>;
@@ -1453,6 +1455,7 @@ export type Apps_Insert_Input = {
postgresSchemaMigrationUser?: InputMaybe<Scalars['String']>;
postgresUser?: InputMaybe<Scalars['String']>;
postgresVersion?: InputMaybe<Scalars['String']>;
providersUpdated?: InputMaybe<Scalars['Boolean']>;
region?: InputMaybe<Regions_Obj_Rel_Insert_Input>;
regionId?: InputMaybe<Scalars['uuid']>;
repositoryProductionBranch?: InputMaybe<Scalars['String']>;
@@ -2070,6 +2073,7 @@ export type Apps_Order_By = {
postgresSchemaMigrationUser?: InputMaybe<Order_By>;
postgresUser?: InputMaybe<Order_By>;
postgresVersion?: InputMaybe<Order_By>;
providersUpdated?: InputMaybe<Order_By>;
region?: InputMaybe<Regions_Order_By>;
regionId?: InputMaybe<Order_By>;
repositoryProductionBranch?: InputMaybe<Order_By>;
@@ -2354,6 +2358,8 @@ export enum Apps_Select_Column {
/** column name */
PostgresVersion = 'postgresVersion',
/** column name */
ProvidersUpdated = 'providersUpdated',
/** column name */
RegionId = 'regionId',
/** column name */
RepositoryProductionBranch = 'repositoryProductionBranch',
@@ -2432,7 +2438,9 @@ export enum Apps_Select_Column_Apps_Aggregate_Bool_Exp_Bool_And_Arguments_Column
/** column name */
Paused = 'paused',
/** column name */
PostgresPublicAccess = 'postgresPublicAccess'
PostgresPublicAccess = 'postgresPublicAccess',
/** column name */
ProvidersUpdated = 'providersUpdated'
}
/** select "apps_aggregate_bool_exp_bool_or_arguments_columns" columns of table "apps" */
@@ -2496,7 +2504,9 @@ export enum Apps_Select_Column_Apps_Aggregate_Bool_Exp_Bool_Or_Arguments_Columns
/** column name */
Paused = 'paused',
/** column name */
PostgresPublicAccess = 'postgresPublicAccess'
PostgresPublicAccess = 'postgresPublicAccess',
/** column name */
ProvidersUpdated = 'providersUpdated'
}
/** input type for updating data in table "apps" */
@@ -2632,6 +2642,7 @@ export type Apps_Set_Input = {
postgresSchemaMigrationUser?: InputMaybe<Scalars['String']>;
postgresUser?: InputMaybe<Scalars['String']>;
postgresVersion?: InputMaybe<Scalars['String']>;
providersUpdated?: InputMaybe<Scalars['Boolean']>;
regionId?: InputMaybe<Scalars['uuid']>;
repositoryProductionBranch?: InputMaybe<Scalars['String']>;
slug?: InputMaybe<Scalars['String']>;
@@ -2840,6 +2851,7 @@ export type Apps_Stream_Cursor_Value_Input = {
postgresSchemaMigrationUser?: InputMaybe<Scalars['String']>;
postgresUser?: InputMaybe<Scalars['String']>;
postgresVersion?: InputMaybe<Scalars['String']>;
providersUpdated?: InputMaybe<Scalars['Boolean']>;
regionId?: InputMaybe<Scalars['uuid']>;
repositoryProductionBranch?: InputMaybe<Scalars['String']>;
slug?: InputMaybe<Scalars['String']>;
@@ -3130,6 +3142,8 @@ export enum Apps_Update_Column {
/** column name */
PostgresVersion = 'postgresVersion',
/** column name */
ProvidersUpdated = 'providersUpdated',
/** column name */
RegionId = 'regionId',
/** column name */
RepositoryProductionBranch = 'repositoryProductionBranch',
@@ -17042,7 +17056,7 @@ export type GetAppQueryVariables = Exact<{
export type GetAppQuery = { __typename?: 'query_root', app?: { __typename?: 'apps', id: any, slug: string, subdomain: string, name: string, createdAt: any, authEmailSigninEmailVerifiedRequired: boolean, authPasswordHibpEnabled: boolean, authEmailPasswordlessEnabled: boolean, authSmsPasswordlessEnabled: boolean, authWebAuthnEnabled: boolean, authClientUrl: string, authEmailTemplateFetchUrl?: string | null, authAccessControlAllowedEmails: string, authAccessControlAllowedEmailDomains: string, authAccessControlBlockedEmails: string, authAccessControlBlockedEmailDomains: string, authAccessControlAllowedRedirectUrls: string, authGithubEnabled: boolean, authGithubClientId: string, authGithubClientSecret: string, authGoogleEnabled: boolean, authGoogleClientId: string, authGoogleClientSecret: string, authFacebookEnabled: boolean, authFacebookClientId: string, authFacebookClientSecret: string, authLinkedinEnabled: boolean, authLinkedinClientId: string, authLinkedinClientSecret: string, authTwitterEnabled: boolean, authTwitterConsumerKey: string, authTwitterConsumerSecret: string, authAppleEnabled: boolean, authAppleTeamId: string, authAppleKeyId: string, authAppleClientId: string, authApplePrivateKey: string, authAppleScope: string, authWindowsLiveEnabled: boolean, authWindowsLiveClientId: string, authWindowsLiveClientSecret: string, authSpotifyEnabled: boolean, authSpotifyClientId: string, authSpotifyClientSecret: string, authWorkOsEnabled: boolean, authWorkOsClientId: string, authWorkOsClientSecret: string, authWorkOsDefaultDomain: string, authWorkOsDefaultOrganization: string, authWorkOsDefaultConnection: string } | null };
export type GetAppByWorkspaceAndNameFragment = { __typename?: 'apps', updatedAt: any, id: any, slug: string, subdomain: string, hasuraGraphqlAdminSecret: string, name: string, createdAt: any, isProvisioned: boolean, repositoryProductionBranch: string, githubRepositoryId?: any | null, workspaceId: any, githubRepository?: { __typename?: 'githubRepositories', id: any, name: string, githubAppInstallation: { __typename?: 'githubAppInstallations', id: any, accountLogin?: string | null } } | null, region: { __typename?: 'regions', countryCode: string, city: string }, workspace: { __typename?: 'workspaces', name: string, slug: string, id: any } };
export type GetAppByWorkspaceAndNameFragment = { __typename?: 'apps', updatedAt: any, id: any, slug: string, subdomain: string, hasuraGraphqlAdminSecret: string, name: string, createdAt: any, isProvisioned: boolean, providersUpdated?: boolean | null, repositoryProductionBranch: string, githubRepositoryId?: any | null, workspaceId: any, githubRepository?: { __typename?: 'githubRepositories', id: any, name: string, githubAppInstallation: { __typename?: 'githubAppInstallations', id: any, accountLogin?: string | null } } | null, region: { __typename?: 'regions', countryCode: string, city: string }, workspace: { __typename?: 'workspaces', name: string, slug: string, id: any } };
export type GetAppByWorkspaceAndNameQueryVariables = Exact<{
workspace: Scalars['String'];
@@ -17050,7 +17064,7 @@ export type GetAppByWorkspaceAndNameQueryVariables = Exact<{
}>;
export type GetAppByWorkspaceAndNameQuery = { __typename?: 'query_root', apps: Array<{ __typename?: 'apps', updatedAt: any, id: any, slug: string, subdomain: string, hasuraGraphqlAdminSecret: string, name: string, createdAt: any, isProvisioned: boolean, repositoryProductionBranch: string, githubRepositoryId?: any | null, workspaceId: any, githubRepository?: { __typename?: 'githubRepositories', id: any, name: string, githubAppInstallation: { __typename?: 'githubAppInstallations', id: any, accountLogin?: string | null } } | null, region: { __typename?: 'regions', countryCode: string, city: string }, workspace: { __typename?: 'workspaces', name: string, slug: string, id: any } }> };
export type GetAppByWorkspaceAndNameQuery = { __typename?: 'query_root', apps: Array<{ __typename?: 'apps', updatedAt: any, id: any, slug: string, subdomain: string, hasuraGraphqlAdminSecret: string, name: string, createdAt: any, isProvisioned: boolean, providersUpdated?: boolean | null, repositoryProductionBranch: string, githubRepositoryId?: any | null, workspaceId: any, githubRepository?: { __typename?: 'githubRepositories', id: any, name: string, githubAppInstallation: { __typename?: 'githubAppInstallations', id: any, accountLogin?: string | null } } | null, region: { __typename?: 'regions', countryCode: string, city: string }, workspace: { __typename?: 'workspaces', name: string, slug: string, id: any } }> };
export type GetAppCustomClaimsQueryVariables = Exact<{
id: Scalars['uuid'];
@@ -17498,6 +17512,13 @@ export type DeleteRemoteAppUserRolesMutationVariables = Exact<{
export type DeleteRemoteAppUserRolesMutation = { __typename?: 'mutation_root', deleteAuthUserRoles?: { __typename?: 'authUserRoles_mutation_response', affected_rows: number } | null };
export type ConfirmProvidersUpdatedMutationVariables = Exact<{
id: Scalars['uuid'];
}>;
export type ConfirmProvidersUpdatedMutation = { __typename?: 'mutation_root', updateApp?: { __typename?: 'apps', id: any } | null };
export type GetDatabaseConnectionInfoQueryVariables = Exact<{
id: Scalars['uuid'];
}>;
@@ -17529,7 +17550,7 @@ export type GetOneUserQueryVariables = Exact<{
}>;
export type GetOneUserQuery = { __typename?: 'query_root', user?: { __typename?: 'users', id: any, displayName: string, avatarUrl: string, workspaceMembers: Array<{ __typename?: 'workspaceMembers', id: any, userId: any, workspaceId: any, type: string, workspace: { __typename?: 'workspaces', creatorUserId?: any | null, id: any, slug: string, name: string, apps: Array<{ __typename?: 'apps', id: any, slug: string, name: string, hasuraGraphqlAdminSecret: string, repositoryProductionBranch: string, subdomain: string, isProvisioned: boolean, createdAt: any, desiredState: number, nhostBaseFolder: string, featureFlags: Array<{ __typename?: 'featureFlags', description: string, id: any, name: string, value: string }>, appStates: Array<{ __typename?: 'appStateHistory', id: any, appId: any, message?: string | null, stateId: number, createdAt: any }>, region: { __typename?: 'regions', id: any, countryCode: string, awsName: string, city: string }, plan: { __typename?: 'plans', id: any, name: string, isFree: boolean }, githubRepository?: { __typename?: 'githubRepositories', fullName: string } | null, deployments: Array<{ __typename?: 'deployments', id: any, commitSHA: string, commitMessage?: string | null, commitUserName?: string | null, deploymentStartedAt?: any | null, deploymentEndedAt?: any | null, commitUserAvatarUrl?: string | null, deploymentStatus?: string | null }> }> } }> } | null };
export type GetOneUserQuery = { __typename?: 'query_root', user?: { __typename?: 'users', id: any, displayName: string, avatarUrl: string, workspaceMembers: Array<{ __typename?: 'workspaceMembers', id: any, userId: any, workspaceId: any, type: string, workspace: { __typename?: 'workspaces', creatorUserId?: any | null, id: any, slug: string, name: string, apps: Array<{ __typename?: 'apps', id: any, slug: string, name: string, hasuraGraphqlAdminSecret: string, repositoryProductionBranch: string, subdomain: string, isProvisioned: boolean, createdAt: any, desiredState: number, nhostBaseFolder: string, providersUpdated?: boolean | null, featureFlags: Array<{ __typename?: 'featureFlags', description: string, id: any, name: string, value: string }>, appStates: Array<{ __typename?: 'appStateHistory', id: any, appId: any, message?: string | null, stateId: number, createdAt: any }>, region: { __typename?: 'regions', id: any, countryCode: string, awsName: string, city: string }, plan: { __typename?: 'plans', id: any, name: string, isFree: boolean }, githubRepository?: { __typename?: 'githubRepositories', fullName: string } | null, deployments: Array<{ __typename?: 'deployments', id: any, commitSHA: string, commitMessage?: string | null, commitUserName?: string | null, deploymentStartedAt?: any | null, deploymentEndedAt?: any | null, commitUserAvatarUrl?: string | null, deploymentStatus?: string | null }> }> } }> } | null };
export type GetUserAllWorkspacesQueryVariables = Exact<{ [key: string]: never; }>;
@@ -17758,6 +17779,7 @@ export const GetAppByWorkspaceAndNameFragmentDoc = gql`
name
createdAt
isProvisioned
providersUpdated
githubRepository {
id
name
@@ -20748,6 +20770,39 @@ export function useDeleteRemoteAppUserRolesMutation(baseOptions?: Apollo.Mutatio
export type DeleteRemoteAppUserRolesMutationHookResult = ReturnType<typeof useDeleteRemoteAppUserRolesMutation>;
export type DeleteRemoteAppUserRolesMutationResult = Apollo.MutationResult<DeleteRemoteAppUserRolesMutation>;
export type DeleteRemoteAppUserRolesMutationOptions = Apollo.BaseMutationOptions<DeleteRemoteAppUserRolesMutation, DeleteRemoteAppUserRolesMutationVariables>;
export const ConfirmProvidersUpdatedDocument = gql`
mutation confirmProvidersUpdated($id: uuid!) {
updateApp(pk_columns: {id: $id}, _set: {providersUpdated: true}) {
id
}
}
`;
export type ConfirmProvidersUpdatedMutationFn = Apollo.MutationFunction<ConfirmProvidersUpdatedMutation, ConfirmProvidersUpdatedMutationVariables>;
/**
* __useConfirmProvidersUpdatedMutation__
*
* To run a mutation, you first call `useConfirmProvidersUpdatedMutation` within a React component and pass it any options that fit your needs.
* When your component renders, `useConfirmProvidersUpdatedMutation` returns a tuple that includes:
* - A mutate function that you can call at any time to execute the mutation
* - An object with fields that represent the current status of the mutation's execution
*
* @param baseOptions options that will be passed into the mutation, supported options are listed on: https://www.apollographql.com/docs/react/api/react-hooks/#options-2;
*
* @example
* const [confirmProvidersUpdatedMutation, { data, loading, error }] = useConfirmProvidersUpdatedMutation({
* variables: {
* id: // value for 'id'
* },
* });
*/
export function useConfirmProvidersUpdatedMutation(baseOptions?: Apollo.MutationHookOptions<ConfirmProvidersUpdatedMutation, ConfirmProvidersUpdatedMutationVariables>) {
const options = {...defaultOptions, ...baseOptions}
return Apollo.useMutation<ConfirmProvidersUpdatedMutation, ConfirmProvidersUpdatedMutationVariables>(ConfirmProvidersUpdatedDocument, options);
}
export type ConfirmProvidersUpdatedMutationHookResult = ReturnType<typeof useConfirmProvidersUpdatedMutation>;
export type ConfirmProvidersUpdatedMutationResult = Apollo.MutationResult<ConfirmProvidersUpdatedMutation>;
export type ConfirmProvidersUpdatedMutationOptions = Apollo.BaseMutationOptions<ConfirmProvidersUpdatedMutation, ConfirmProvidersUpdatedMutationVariables>;
export const GetDatabaseConnectionInfoDocument = gql`
query getDatabaseConnectionInfo($id: uuid!) {
app(id: $id) {
@@ -20991,6 +21046,7 @@ export const GetOneUserDocument = gql`
createdAt
desiredState
nhostBaseFolder
providersUpdated
featureFlags {
description
id

View File

@@ -72,6 +72,26 @@ export function generateRemoteAppUrl(subdomain: string): string {
return `https://${subdomain}.nhost.run`;
}
export function generateAppServiceUrl(
subdomain: string,
region: string,
service: 'auth' | 'graphql' | 'functions' | 'storage' | 'hasura',
) {
if (process.env.NEXT_PUBLIC_NHOST_PLATFORM !== 'true') {
return LOCAL_BACKEND_URL;
}
if (process.env.NEXT_PUBLIC_ENV === 'dev') {
return process.env.NEXT_PUBLIC_NHOST_BACKEND_URL || LOCAL_BACKEND_URL;
}
if (process.env.NEXT_PUBLIC_ENV === 'staging') {
return `https://${subdomain}.${service}.${region}.staging.nhost.run`;
}
return `https://${subdomain}.${service}.${region}.nhost.run`;
}
export function emptyWorkspace() {
return {
id: '',

View File

@@ -40,7 +40,7 @@ query {
Users should be created using the sign-up or sign-in flows as described under [sign-in methods](/authentication/sign-in-methods).
- **Never** create users directly via GraphQL or database, unless you [import users](#import-users) from an external system.
- **Never** modify the `auth.users` table.
- **Never** modify the database schema for the `auth.users` table.
- **Never** modify the GraphQL root queries or fields for any of the tables in the `auth` schema.
You're allowed to:

View File

@@ -0,0 +1,65 @@
/*
- How to receive Stripe Webhooks. Read more about Stripe Webhooks here: https://stripe.com/docs/webhooks.
- Make sure to configure your Stripe Webhook URL in the Stripe Dashboard: https://dashboard.stripe.com/webhooks.
- You can test your Stripe Webhook by using the Stripe CLI: https://stripe.com/docs/stripe-cli.
- Make sure to configure `STRIPE_SECRET_KEY` and `STRIPE_WEBHOOK_SECRET` in your `.env.development` file during local development. In production, use the `Environment Variables` tab in the Nhost Dashboard.
Test:
URL: http://localhost:1337/v1/functions/stripe-webhook
*/
import { Request, Response } from 'express'
import Stripe from 'stripe'
type NhostResponse = Response
type NhostRequest = Request & {
rawBody: string
}
export const stripe = new Stripe(process.env.STRIPE_SECRET_KEY, {
apiVersion: '2022-08-01'
})
export default async function handler(req: NhostRequest, res: NhostResponse) {
const sig = req.headers['stripe-signature'] as string
const endpointSecret = process.env.STRIPE_WEBHOOK_SECRET
let event
// Match the raw body to content type application/json
try {
event = stripe.webhooks.constructEvent(req.rawBody, sig, endpointSecret)
} catch (err: any) {
console.log(`⚠️ Webhook signature verification failed.`)
console.log(err)
return res.status(400).send(`Webhook Error: ${err.message}`)
}
if (!event) {
console.log('no event found')
return res.status(400).send('No event')
}
// Handle the event
switch (event.type) {
case 'customer.subscription.created': {
const { object } = event.data as any
console.log('customer subscription created!')
console.log(object)
break
}
case 'customer.subscription.deleted': {
const { object } = event.data as any
console.log('customer subscription deleted!')
console.log(object)
}
// ... handle other event types
default:
console.log(`Unhandled event type ${event.type}`)
}
res.json({ received: true })
}

View File

@@ -12,6 +12,7 @@
"cross-fetch": "^3.1.5",
"graphql": "15.7.2",
"nodemailer": "^6.8.0",
"slugify": "^1.6.5"
"slugify": "^1.6.5",
"stripe": "^11.1.0"
}
}

View File

@@ -33,7 +33,7 @@
"typescript": "^4.8.4"
},
"dependencies": {
"@pnpm/find-workspace-dir": "^4.0.3",
"@pnpm/find-workspace-dir": "^5.0.0",
"glob": "^8.0.3",
"object-path": "^0.11.8",
"yaml": "^2.1.1"

View File

@@ -1,13 +1,11 @@
#!/usr/bin/env node
import { findWorkspaceDir } from '@pnpm/find-workspace-dir'
import fs from 'fs'
import path from 'path'
import glob from 'glob'
import { set } from 'object-path'
import path from 'path'
import yaml from 'yaml'
import findWorkspaceRoot from '@pnpm/find-workspace-dir'
interface NhostCloudConfig {
hasura: string
auth: string
@@ -15,7 +13,7 @@ interface NhostCloudConfig {
}
const main = async () => {
const root = await findWorkspaceRoot(process.cwd())
const root = await findWorkspaceDir(process.cwd())
const { hasura, auth, storage }: NhostCloudConfig = yaml.parse(
fs.readFileSync(path.join(root!, 'nhost-cloud.yaml'), 'utf-8')

View File

@@ -67,8 +67,8 @@
"@nhost/core": "workspace:*",
"@nhost/hasura-storage-js": "workspace:*",
"@nhost/nhost-js": "workspace:*",
"@vueuse/core": "^8.9.4",
"@xstate/vue": "^1.0.0",
"@vueuse/core": "^9.0.0",
"@xstate/vue": "^2.0.0",
"immer": "^9.0.15",
"jwt-decode": "^3.1.2"
},

127
pnpm-lock.yaml generated
View File

@@ -156,7 +156,7 @@ importers:
eslint-plugin-react: ^7.31.11
eslint-plugin-react-hooks: ^4.6.0
generate-password: ^1.7.0
graphiql: ^2.1.0
graphiql: ^2.2.0
graphql: 15.7.2
graphql-request: ^4.3.0
graphql-tag: ^2.12.6
@@ -239,7 +239,7 @@ importers:
cross-fetch: 3.1.5
date-fns: 2.29.3
generate-password: 1.7.0
graphiql: 2.1.0_te5rle7gmjg3syudiw42pabya4
graphiql: 2.2.0_te5rle7gmjg3syudiw42pabya4
graphql: 15.7.2
graphql-request: 4.3.0_graphql@15.7.2
graphql-tag: 2.12.6_graphql@15.7.2
@@ -629,6 +629,7 @@ importers:
graphql: 15.7.2
nodemailer: ^6.8.0
slugify: ^1.6.5
stripe: ^11.1.0
dependencies:
'@graphql-yoga/node': 2.13.13_graphql@15.7.2
'@nhost/stripe-graphql-js': link:../../integrations/stripe-graphql-js
@@ -637,6 +638,7 @@ importers:
graphql: 15.7.2
nodemailer: 6.8.0
slugify: 1.6.5
stripe: 11.1.0
devDependencies:
'@types/express': 4.17.13
@@ -1000,7 +1002,7 @@ importers:
packages/sync-versions:
specifiers:
'@pnpm/find-workspace-dir': ^4.0.3
'@pnpm/find-workspace-dir': ^5.0.0
'@swc-node/register': ^1.5.4
'@swc/core': ^1.3.11
'@types/glob': ^8.0.0
@@ -1011,7 +1013,7 @@ importers:
typescript: ^4.8.4
yaml: ^2.1.1
dependencies:
'@pnpm/find-workspace-dir': 4.0.3
'@pnpm/find-workspace-dir': 5.0.0
glob: 8.0.3
object-path: 0.11.8
yaml: 2.1.1
@@ -1031,9 +1033,9 @@ importers:
'@nhost/hasura-storage-js': workspace:*
'@nhost/nhost-js': workspace:*
'@vitejs/plugin-vue': ^3.2.0
'@vueuse/core': ^8.9.4
'@vueuse/core': ^9.0.0
'@xstate/inspect': ^0.7.0
'@xstate/vue': ^1.0.0
'@xstate/vue': ^2.0.0
immer: ^9.0.15
jwt-decode: ^3.1.2
vue: ^3.2.41
@@ -1044,8 +1046,8 @@ importers:
'@nhost/core': link:../core
'@nhost/hasura-storage-js': link:../hasura-storage-js
'@nhost/nhost-js': link:../nhost-js
'@vueuse/core': 8.9.4_vue@3.2.41
'@xstate/vue': 1.0.0_vue@3.2.41+xstate@4.33.6
'@vueuse/core': 9.6.0_vue@3.2.41
'@xstate/vue': 2.0.0_vue@3.2.41+xstate@4.33.6
immer: 9.0.15
jwt-decode: 3.1.2
devDependencies:
@@ -4968,37 +4970,6 @@ packages:
/@gqty/utils/1.0.0:
resolution: {integrity: sha512-QJMlzts//d0H5mlekOZgx1a4KsTYXfxmRhhx8g/8mvzdaNVPxhFzCsv3+ljTOzbW3A08qy4jXQPWAMoTefSJDQ==}
/@graphiql/react/0.14.0_te5rle7gmjg3syudiw42pabya4:
resolution: {integrity: sha512-BBkbl35akar4/+4P6ggZ99jSmU0D1qV70A2OegkuJ4t/knAis/R713faOs9xKyjkUj8hv6+KcAqBOp48LnP6lA==}
peerDependencies:
graphql: ^15.5.0 || ^16.0.0
react: ^16.8.0 || ^17.0.0 || ^18.0.0
react-dom: ^16.8.0 || ^17.0.0 || ^18.0.0
dependencies:
'@graphiql/toolkit': 0.8.0_e4cx3o37mthaippf56xwzxw5re
'@reach/combobox': 0.17.0_biqbaboplfbrettd7655fr4n2y
'@reach/dialog': 0.17.0_2zx2umvpluuhvlq44va5bta2da
'@reach/listbox': 0.17.0_biqbaboplfbrettd7655fr4n2y
'@reach/menu-button': 0.17.0_pumtretovylab5lwhztzjp2kuy
'@reach/tooltip': 0.17.0_biqbaboplfbrettd7655fr4n2y
'@reach/visually-hidden': 0.17.0_biqbaboplfbrettd7655fr4n2y
codemirror: 5.65.9
codemirror-graphql: 2.0.2_iqwfwa2i4p54k5bdy4wsg4tww4
copy-to-clipboard: 3.3.3
graphql: 15.7.2
graphql-language-service: 5.1.0_graphql@15.7.2
markdown-it: 12.3.2
react: 18.2.0
react-dom: 18.2.0_react@18.2.0
set-value: 4.1.0
transitivePeerDependencies:
- '@codemirror/language'
- '@types/node'
- '@types/react'
- graphql-ws
- react-is
dev: false
/@graphiql/react/0.15.0_te5rle7gmjg3syudiw42pabya4:
resolution: {integrity: sha512-kJqkdf6d4Cck05Wt5yCDZXWfs7HZgcpuoWq/v8nOa698qVaNMM3qdG4CpRsZEexku0DSSJzWWuanxd5x+sRcFg==}
peerDependencies:
@@ -7173,18 +7144,18 @@ packages:
engines: {node: '>=14.19'}
dev: false
/@pnpm/error/3.1.0:
resolution: {integrity: sha512-bmXBD/kzlgHqlIZPP8QJUDAxGqug2qhPdnqNnuXyWQSyIEgeaXyPiUh91MLj9GwLoHA9Zdrx5+dfEougzxf4mA==}
/@pnpm/error/4.0.0:
resolution: {integrity: sha512-NI4DFCMF6xb1SA0bZiiV5KrMCaJM2QmPJFC6p78FXujn7FpiRSWhT9r032wpuQumsl7DEmN4s3wl/P8TA+bL8w==}
engines: {node: '>=14.6'}
dependencies:
'@pnpm/constants': 6.1.0
dev: false
/@pnpm/find-workspace-dir/4.0.3:
resolution: {integrity: sha512-BE0LFHCtcjxTUC/R3MMNuHkOtm559g/ObbIOjCjO3h3I9fFsxt7fVtRwaYbfS6NJk7DrzDsPOfFBdX2NipR8iw==}
/@pnpm/find-workspace-dir/5.0.0:
resolution: {integrity: sha512-x/OERjU3BjUyxrHSl5Zuqqo6PmtbPo4Xi8ypD98wQ/OcUJ1ZCQ276vP2n4E89N5Mb70N2J+4J1dnmPW+OnpEQg==}
engines: {node: '>=14.6'}
dependencies:
'@pnpm/error': 3.1.0
'@pnpm/error': 4.0.0
find-up: 5.0.0
dev: false
@@ -10197,6 +10168,10 @@ packages:
/@types/web-bluetooth/0.0.14:
resolution: {integrity: sha512-5d2RhCard1nQUC3aHcq/gHzWYO6K0WJmAbjO7mQJgCQKtZpgXxv1rOM6O/dBDhDYYVutk1sciOgNSe+5YyfM8A==}
/@types/web-bluetooth/0.0.16:
resolution: {integrity: sha512-oh8q2Zc32S6gd/j50GowEjKLoOVOwHP/bWVjKJInBwQqdOYMdPrf1oVlelTlyfFK3CKxL1uahMDAr+vy8T7yMQ==}
dev: false
/@types/webfontloader/1.6.35:
resolution: {integrity: sha512-IJlrsiDWq6KghQ7tPlL5tcwSUyOxLDceT+AFUY7Ylj0Fcv3/h3QkANqQxZ0B5mEpEKxhTw76vDmvrruSMV9n9Q==}
dev: true
@@ -11270,27 +11245,25 @@ packages:
vue: 3.2.40
vue-demi: 0.13.4_vue@3.2.40
/@vueuse/core/8.9.4_vue@3.2.41:
resolution: {integrity: sha512-B/Mdj9TK1peFyWaPof+Zf/mP9XuGAngaJZBwPaXBvU3aCTZlx3ltlrFFFyMV4iGBwsjSCeUCgZrtkEj9dS2Y3Q==}
peerDependencies:
'@vue/composition-api': ^1.1.0
vue: ^2.6.0 || ^3.2.0
peerDependenciesMeta:
'@vue/composition-api':
optional: true
vue:
optional: true
/@vueuse/core/9.6.0_vue@3.2.41:
resolution: {integrity: sha512-qGUcjKQXHgN+jqXEgpeZGoxdCbIDCdVPz3QiF1uyecVGbMuM63o96I1GjYx5zskKgRI0FKSNsVWM7rwrRMTf6A==}
dependencies:
'@types/web-bluetooth': 0.0.14
'@vueuse/metadata': 8.9.4
'@vueuse/shared': 8.9.4_vue@3.2.41
vue: 3.2.41
'@types/web-bluetooth': 0.0.16
'@vueuse/metadata': 9.6.0
'@vueuse/shared': 9.6.0_vue@3.2.41
vue-demi: 0.13.4_vue@3.2.41
transitivePeerDependencies:
- '@vue/composition-api'
- vue
dev: false
/@vueuse/metadata/8.9.4:
resolution: {integrity: sha512-IwSfzH80bnJMzqhaapqJl9JRIiyQU0zsRGEgnxN6jhq7992cPUJIRfV+JHRIZXjYqbwt07E1gTEp0R0zPJ1aqw==}
/@vueuse/metadata/9.6.0:
resolution: {integrity: sha512-sIC8R+kWkIdpi5X2z2Gk8TRYzmczDwHRhEFfCu2P+XW2JdPoXrziqsGpDDsN7ykBx4ilwieS7JUIweVGhvZ93w==}
dev: false
/@vueuse/shared/8.9.4_vue@3.2.40:
resolution: {integrity: sha512-wt+T30c4K6dGRMVqPddexEVLa28YwxW5OFIPmzUHICjphfAuBFTTdDoyqREZNDOFJZ44ARH1WWQNCUK8koJ+Ag==}
peerDependencies:
@@ -11305,19 +11278,13 @@ packages:
vue: 3.2.40
vue-demi: 0.13.4_vue@3.2.40
/@vueuse/shared/8.9.4_vue@3.2.41:
resolution: {integrity: sha512-wt+T30c4K6dGRMVqPddexEVLa28YwxW5OFIPmzUHICjphfAuBFTTdDoyqREZNDOFJZ44ARH1WWQNCUK8koJ+Ag==}
peerDependencies:
'@vue/composition-api': ^1.1.0
vue: ^2.6.0 || ^3.2.0
peerDependenciesMeta:
'@vue/composition-api':
optional: true
vue:
optional: true
/@vueuse/shared/9.6.0_vue@3.2.41:
resolution: {integrity: sha512-/eDchxYYhkHnFyrb00t90UfjCx94kRHxc7J1GtBCqCG4HyPMX+krV9XJgVtWIsAMaxKVU4fC8NSUviG1JkwhUQ==}
dependencies:
vue: 3.2.41
vue-demi: 0.13.4_vue@3.2.41
transitivePeerDependencies:
- '@vue/composition-api'
- vue
dev: false
/@webassemblyjs/ast/1.11.1:
@@ -11665,12 +11632,12 @@ packages:
- '@types/react'
dev: false
/@xstate/vue/1.0.0_vue@3.2.41+xstate@4.33.6:
resolution: {integrity: sha512-GnJ2WKmef3UvpOj7tMOGkFLF2fSjVFgX/2Ik/0ZttHJCQNXRBWDaaiqNnVVB0XynTUfRPrkOPNeGD4XLqrqeVg==}
/@xstate/vue/2.0.0_vue@3.2.41+xstate@4.33.6:
resolution: {integrity: sha512-JlrJ3d+I6rZCcFBuu3O4GP+mGJfd11O9o69wRedzPMqZ+hxcMRBsih9L5kKnJHcU9CTmdJTT172oxTaYF7thzA==}
peerDependencies:
'@xstate/fsm': ^1.6.5
'@xstate/fsm': ^2.0.0
vue: ^3.0.0
xstate: ^4.30.3
xstate: ^4.31.0
peerDependenciesMeta:
'@xstate/fsm':
optional: true
@@ -19027,14 +18994,14 @@ packages:
resolution: {integrity: sha512-bzh50DW9kTPM00T8y4o8vQg89Di9oLJVLW/KaOGIXJWP/iqCN6WKYkbNOF04vFLJhwcpYUh9ydh/+5vpOqV4YQ==}
dev: true
/graphiql/2.1.0_te5rle7gmjg3syudiw42pabya4:
resolution: {integrity: sha512-b58o/o7y5x/C4WzH7YTeSWbINE6tcfzZN4TxgvoSZxhE9X6MulXXbXLRiGEl5+FuajIN0LxaoleHTJUHb9H2wg==}
/graphiql/2.2.0_te5rle7gmjg3syudiw42pabya4:
resolution: {integrity: sha512-w1ujpCKMlkwkoUjeg0HpRiBBTm1WHAjHNkFv1TbMu6trjzz63mQ48GLZlmyQY1yhwmc+diCcvmmAt+AyvKLWWA==}
peerDependencies:
graphql: ^15.5.0 || ^16.0.0
react: ^16.8.0 || ^17.0.0 || ^18.0.0
react-dom: ^16.8.0 || ^17.0.0 || ^18.0.0
dependencies:
'@graphiql/react': 0.14.0_te5rle7gmjg3syudiw42pabya4
'@graphiql/react': 0.15.0_te5rle7gmjg3syudiw42pabya4
'@graphiql/toolkit': 0.8.0_e4cx3o37mthaippf56xwzxw5re
entities: 2.2.0
graphql: 15.7.2
@@ -26750,6 +26717,14 @@ packages:
qs: 6.11.0
dev: false
/stripe/11.1.0:
resolution: {integrity: sha512-erOslPQZSYKOotQjmKRy4eBon/tdhzLIYzBdPSNVWDdatSQozkkPlh8mVeXNwubYYZYx61/yS23eWiGDF93z2w==}
engines: {node: '>=12.*'}
dependencies:
'@types/node': 18.11.9
qs: 6.11.0
dev: false
/stubs/3.0.0:
resolution: {integrity: sha512-PdHt7hHUJKxvTCgbKX9C1V/ftOcjJQgz8BZwNfV5c4B6dcGqlpelTbJ999jBGZ2jYiPAwcX5dP6oBwVlBlUbxw==}
dev: false