Compare commits
23 Commits
@nhost/rea
...
@nhost/apo
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
a654d536e0 | ||
|
|
91c2bb6f53 | ||
|
|
9f2bf9ec2b | ||
|
|
d62bd0fc9a | ||
|
|
768ca17494 | ||
|
|
943831fe2e | ||
|
|
f242e4b92f | ||
|
|
863b37d313 | ||
|
|
c8a8d4fca3 | ||
|
|
311374e3fb | ||
|
|
e40a4529b4 | ||
|
|
1623e9bd20 | ||
|
|
5c47e8e675 | ||
|
|
9f9f1c64f4 | ||
|
|
981404f0b9 | ||
|
|
4ad27e9d72 | ||
|
|
778946998a | ||
|
|
6c11b75807 | ||
|
|
2dc031d16c | ||
|
|
40bd3e4572 | ||
|
|
6cb2b6331a | ||
|
|
08a7dd9894 | ||
|
|
f0a994a26e |
@@ -1,5 +1,46 @@
|
||||
# @nhost/dashboard
|
||||
|
||||
## 1.12.0
|
||||
|
||||
### Minor Changes
|
||||
|
||||
- f242e4b: feat: add connect with github to the user's account settings
|
||||
- 768ca17: chore: update dependencies
|
||||
- d62bd0f: fix: "Track this" option within the SQL editor now correctly updates the metadata
|
||||
- 91c2bb6: feat: refactor sign-in and sign-up pages to enforce email verification
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- 943831f: fix: resolve an error toast issue when unpausing a project
|
||||
- Updated dependencies [768ca17]
|
||||
- @nhost/react-apollo@11.0.0
|
||||
- @nhost/nextjs@2.1.9
|
||||
|
||||
## 1.11.2
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- @nhost/react-apollo@10.0.2
|
||||
- @nhost/nextjs@2.1.8
|
||||
|
||||
## 1.11.1
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- 981404f: fix: set default value for healthCheck field validation
|
||||
|
||||
## 1.11.0
|
||||
|
||||
### Minor Changes
|
||||
|
||||
- 7789469: chore: upgrade dependency `@graphql-codegen/cli` to `5.0.2` to address vulnerability
|
||||
- 6c11b75: feat: add update user displayName section in account settings
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- @nhost/react-apollo@10.0.1
|
||||
- @nhost/nextjs@2.1.7
|
||||
|
||||
## 1.10.0
|
||||
|
||||
### Minor Changes
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@nhost/dashboard",
|
||||
"version": "1.10.0",
|
||||
"version": "1.12.0",
|
||||
"private": true,
|
||||
"scripts": {
|
||||
"preinstall": "npx only-allow pnpm",
|
||||
@@ -19,34 +19,34 @@
|
||||
"e2e": "pnpm install-browsers && pnpm playwright test"
|
||||
},
|
||||
"dependencies": {
|
||||
"@apollo/client": "^3.9.5",
|
||||
"@codemirror/lang-sql": "^6.6.0",
|
||||
"@apollo/client": "^3.9.9",
|
||||
"@codemirror/lang-sql": "^6.6.2",
|
||||
"@emotion/cache": "^11.11.0",
|
||||
"@emotion/react": "^11.11.4",
|
||||
"@emotion/server": "^11.11.0",
|
||||
"@emotion/styled": "^11.11.0",
|
||||
"@fontsource/inter": "^5.0.16",
|
||||
"@fontsource/roboto-mono": "^5.0.16",
|
||||
"@emotion/styled": "^11.11.5",
|
||||
"@fontsource/inter": "^5.0.17",
|
||||
"@fontsource/roboto-mono": "^5.0.17",
|
||||
"@graphiql/react": "^0.20.3",
|
||||
"@graphiql/toolkit": "^0.9.1",
|
||||
"@headlessui/react": "^1.7.18",
|
||||
"@heroicons/react": "^1.0.6",
|
||||
"@hookform/resolvers": "^3.3.4",
|
||||
"@mui/base": "5.0.0-beta.31",
|
||||
"@mui/material": "^5.15.11",
|
||||
"@mui/system": "^5.15.11",
|
||||
"@mui/material": "^5.15.14",
|
||||
"@mui/system": "^5.15.14",
|
||||
"@mui/x-date-pickers": "^5.0.20",
|
||||
"@nhost/nextjs": "workspace:*",
|
||||
"@nhost/react-apollo": "workspace:*",
|
||||
"@segment/snippet": "^4.16.2",
|
||||
"@stripe/react-stripe-js": "^2.5.1",
|
||||
"@stripe/react-stripe-js": "^2.6.2",
|
||||
"@stripe/stripe-js": "^1.54.2",
|
||||
"@tailwindcss/forms": "^0.5.7",
|
||||
"@tanstack/react-query": "^4.36.1",
|
||||
"@tanstack/react-table": "^8.13.2",
|
||||
"@tanstack/react-virtual": "^3.1.3",
|
||||
"@uiw/codemirror-theme-github": "^4.21.24",
|
||||
"@uiw/react-codemirror": "^4.21.24",
|
||||
"@tanstack/react-table": "^8.15.3",
|
||||
"@tanstack/react-virtual": "^3.2.0",
|
||||
"@uiw/codemirror-theme-github": "^4.21.25",
|
||||
"@uiw/react-codemirror": "^4.21.25",
|
||||
"analytics-node": "^6.2.0",
|
||||
"bcryptjs": "^2.4.3",
|
||||
"clsx": "^1.2.1",
|
||||
@@ -57,10 +57,10 @@
|
||||
"graphql": "16.8.1",
|
||||
"graphql-request": "^6.1.0",
|
||||
"graphql-tag": "^2.12.6",
|
||||
"graphql-ws": "^5.15.0",
|
||||
"graphql-ws": "^5.16.0",
|
||||
"just-kebab-case": "^4.2.0",
|
||||
"lodash.debounce": "^4.0.8",
|
||||
"next": "^14.1.0",
|
||||
"next": "^14.1.4",
|
||||
"next-seo": "^6.5.0",
|
||||
"node-pg-format": "^1.3.5",
|
||||
"pluralize": "^8.0.0",
|
||||
@@ -68,7 +68,7 @@
|
||||
"react-children-utilities": "^2.10.0",
|
||||
"react-dom": "18.2.0",
|
||||
"react-error-boundary": "^4.0.13",
|
||||
"react-hook-form": "^7.50.1",
|
||||
"react-hook-form": "^7.51.2",
|
||||
"react-hot-toast": "^2.4.1",
|
||||
"react-intersection-observer": "^9.8.1",
|
||||
"react-is": "18.2.0",
|
||||
@@ -87,13 +87,13 @@
|
||||
"tailwind-merge": "^1.14.0",
|
||||
"utility-types": "^3.11.0",
|
||||
"validator": "^13.11.0",
|
||||
"yup": "^1.3.3",
|
||||
"yup": "^1.4.0",
|
||||
"yup-password": "^0.2.2"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@babel/core": "^7.24.0",
|
||||
"@babel/core": "^7.24.3",
|
||||
"@faker-js/faker": "^7.6.0",
|
||||
"@graphql-codegen/cli": "^3.3.1",
|
||||
"@graphql-codegen/cli": "^5.0.2",
|
||||
"@graphql-codegen/typescript": "^3.0.4",
|
||||
"@graphql-codegen/typescript-operations": "^3.0.4",
|
||||
"@graphql-codegen/typescript-react-apollo": "^3.3.7",
|
||||
@@ -108,20 +108,20 @@
|
||||
"@storybook/manager-webpack5": "^6.5.16",
|
||||
"@storybook/react": "^7.6.17",
|
||||
"@storybook/testing-library": "^0.2.2",
|
||||
"@tailwindcss/typography": "^0.5.10",
|
||||
"@tailwindcss/typography": "^0.5.12",
|
||||
"@testing-library/dom": "^9.3.4",
|
||||
"@testing-library/jest-dom": "^5.17.0",
|
||||
"@testing-library/react": "^14.2.1",
|
||||
"@testing-library/react": "^14.2.2",
|
||||
"@testing-library/user-event": "^14.5.2",
|
||||
"@types/ace": "^0.0.48",
|
||||
"@types/bcryptjs": "^2.4.6",
|
||||
"@types/jest": "^29.5.12",
|
||||
"@types/lodash.debounce": "^4.0.9",
|
||||
"@types/node": "^16.18.86",
|
||||
"@types/node": "^16.18.93",
|
||||
"@types/pluralize": "^0.0.30",
|
||||
"@types/react": "^18.2.61",
|
||||
"@types/react-dom": "^18.2.19",
|
||||
"@types/react-table": "^7.7.19",
|
||||
"@types/react": "^18.2.73",
|
||||
"@types/react-dom": "^18.2.23",
|
||||
"@types/react-table": "^7.7.20",
|
||||
"@types/shell-quote": "^1.7.5",
|
||||
"@types/testing-library__jest-dom": "^5.14.9",
|
||||
"@types/validator": "^13.11.9",
|
||||
@@ -129,7 +129,7 @@
|
||||
"@typescript-eslint/parser": "^6.21.0",
|
||||
"@vitejs/plugin-react": "^4.2.1",
|
||||
"@vitest/coverage-v8": "^0.32.4",
|
||||
"autoprefixer": "^10.4.17",
|
||||
"autoprefixer": "^10.4.19",
|
||||
"babel-loader": "^8.3.0",
|
||||
"babel-plugin-transform-remove-console": "^6.9.4",
|
||||
"csstype": "^3.1.3",
|
||||
@@ -142,14 +142,14 @@
|
||||
"eslint-config-prettier": "^8.10.0",
|
||||
"eslint-plugin-import": "^2.29.1",
|
||||
"eslint-plugin-jsx-a11y": "^6.8.0",
|
||||
"eslint-plugin-react": "^7.33.2",
|
||||
"eslint-plugin-react": "^7.34.1",
|
||||
"eslint-plugin-react-hooks": "^4.6.0",
|
||||
"jsdom": "^22.1.0",
|
||||
"lint-staged": "^15.2.2",
|
||||
"msw": "^1.3.2",
|
||||
"msw": "^1.3.3",
|
||||
"msw-storybook-addon": "^1.10.0",
|
||||
"node-fetch": "^3.3.2",
|
||||
"postcss": "^8.4.35",
|
||||
"postcss": "^8.4.38",
|
||||
"prettier": "^2.8.8",
|
||||
"prettier-plugin-organize-imports": "^3.2.4",
|
||||
"prettier-plugin-tailwindcss": "^0.4.1",
|
||||
@@ -157,11 +157,11 @@
|
||||
"require-from-string": "^2.0.2",
|
||||
"snake-case": "^3.0.4",
|
||||
"storybook-addon-next-router": "^4.0.2",
|
||||
"tailwindcss": "^3.4.1",
|
||||
"tailwindcss": "^3.4.3",
|
||||
"ts-node": "^10.9.2",
|
||||
"tsconfig-paths-webpack-plugin": "^4.1.0",
|
||||
"vite": "^5.1.4",
|
||||
"vite-tsconfig-paths": "^4.3.1",
|
||||
"vite": "^5.2.7",
|
||||
"vite-tsconfig-paths": "^4.3.2",
|
||||
"vitest": "^0.32.4"
|
||||
},
|
||||
"browserslist": {
|
||||
|
||||
@@ -0,0 +1,85 @@
|
||||
import { Form } from '@/components/form/Form';
|
||||
import { SettingsContainer } from '@/components/layout/SettingsContainer';
|
||||
import { Input } from '@/components/ui/v2/Input';
|
||||
import { execPromiseWithErrorToast } from '@/utils/execPromiseWithErrorToast';
|
||||
import { useUpdateUserDisplayNameMutation } from '@/utils/__generated__/graphql';
|
||||
import { yupResolver } from '@hookform/resolvers/yup';
|
||||
import { useUserData } from '@nhost/nextjs';
|
||||
import { FormProvider, useForm } from 'react-hook-form';
|
||||
import * as Yup from 'yup';
|
||||
|
||||
const validationSchema = Yup.object({
|
||||
displayName: Yup.string()
|
||||
.label('Display Name')
|
||||
.required('This field is required.'),
|
||||
});
|
||||
|
||||
export type DisplayNameSettingFormValues = Yup.InferType<
|
||||
typeof validationSchema
|
||||
>;
|
||||
|
||||
export default function DisplayNameSetting() {
|
||||
const { id: userID, displayName } = useUserData();
|
||||
|
||||
const [updateUserDisplayName] = useUpdateUserDisplayNameMutation();
|
||||
|
||||
const form = useForm<DisplayNameSettingFormValues>({
|
||||
reValidateMode: 'onSubmit',
|
||||
defaultValues: {
|
||||
displayName,
|
||||
},
|
||||
resolver: yupResolver(validationSchema),
|
||||
});
|
||||
|
||||
const { register, formState } = form;
|
||||
const isDirty = Object.keys(formState.dirtyFields).length > 0;
|
||||
|
||||
async function handleSubmit(formValues: DisplayNameSettingFormValues) {
|
||||
await execPromiseWithErrorToast(
|
||||
async () => {
|
||||
await updateUserDisplayName({
|
||||
variables: {
|
||||
id: userID,
|
||||
displayName: formValues.displayName,
|
||||
},
|
||||
});
|
||||
|
||||
form.reset({ displayName: formValues.displayName });
|
||||
},
|
||||
{
|
||||
loadingMessage: 'Updating your display name...',
|
||||
successMessage: 'Your display name has been updated successfully.',
|
||||
errorMessage:
|
||||
'An error occurred while trying to update your display name. Please try again.',
|
||||
},
|
||||
);
|
||||
}
|
||||
|
||||
return (
|
||||
<FormProvider {...form}>
|
||||
<Form onSubmit={handleSubmit}>
|
||||
<SettingsContainer
|
||||
title="Update your display name"
|
||||
slotProps={{
|
||||
submitButton: {
|
||||
disabled: !isDirty,
|
||||
loading: formState.isSubmitting,
|
||||
},
|
||||
}}
|
||||
className="grid grid-flow-row lg:grid-cols-5"
|
||||
>
|
||||
<Input
|
||||
{...register('displayName')}
|
||||
className="col-span-2"
|
||||
type="text"
|
||||
id="display-name"
|
||||
label="Display Name"
|
||||
fullWidth
|
||||
helperText={formState.errors.displayName?.message}
|
||||
error={Boolean(formState.errors.displayName)}
|
||||
/>
|
||||
</SettingsContainer>
|
||||
</Form>
|
||||
</FormProvider>
|
||||
);
|
||||
}
|
||||
@@ -0,0 +1,2 @@
|
||||
export * from './DisplayNameSetting';
|
||||
export { default as DisplayNameSetting } from './DisplayNameSetting';
|
||||
@@ -0,0 +1,76 @@
|
||||
import { SettingsContainer } from '@/components/layout/SettingsContainer';
|
||||
import { ActivityIndicator } from '@/components/ui/v2/ActivityIndicator';
|
||||
import { Box } from '@/components/ui/v2/Box';
|
||||
import { Button } from '@/components/ui/v2/Button';
|
||||
import { GitHubIcon } from '@/components/ui/v2/icons/GitHubIcon';
|
||||
import { Text } from '@/components/ui/v2/Text';
|
||||
import { useGetAuthUserProvidersQuery } from '@/utils/__generated__/graphql';
|
||||
import { useProviderLink } from '@nhost/nextjs';
|
||||
import NavLink from 'next/link';
|
||||
|
||||
export default function SocialProvidersSettings() {
|
||||
const { data, loading, error } = useGetAuthUserProvidersQuery();
|
||||
const isGithubConnected = data?.authUserProviders?.some(
|
||||
(item) => item.providerId === 'github',
|
||||
);
|
||||
|
||||
const { github } = useProviderLink({
|
||||
connect: true,
|
||||
redirectTo: `${window.location.origin}/account`,
|
||||
});
|
||||
|
||||
if (!data && loading) {
|
||||
return (
|
||||
<ActivityIndicator
|
||||
delay={1000}
|
||||
label="Loading personal access tokens..."
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
||||
if (error) {
|
||||
throw error;
|
||||
}
|
||||
|
||||
return (
|
||||
<SettingsContainer
|
||||
title="Authentication providers"
|
||||
description=""
|
||||
rootClassName="gap-0 flex flex-col items-start"
|
||||
className="my-2"
|
||||
slotProps={{
|
||||
submitButton: { className: 'hidden' },
|
||||
footer: { className: 'hidden' },
|
||||
}}
|
||||
>
|
||||
{isGithubConnected ? (
|
||||
<Box
|
||||
sx={{ backgroundColor: 'grey.200' }}
|
||||
className="flex flex-row items-center justify-start space-x-2 rounded-md p-2"
|
||||
>
|
||||
<GitHubIcon />
|
||||
<Text className="font-medium ">Connected</Text>
|
||||
</Box>
|
||||
) : (
|
||||
<Box>
|
||||
<NavLink
|
||||
href={github}
|
||||
passHref
|
||||
target="_blank"
|
||||
rel="noreferrer noopener"
|
||||
legacyBehavior
|
||||
>
|
||||
<Button
|
||||
className=""
|
||||
variant="outlined"
|
||||
color="secondary"
|
||||
startIcon={<GitHubIcon />}
|
||||
>
|
||||
Connect with GitHub
|
||||
</Button>
|
||||
</NavLink>
|
||||
</Box>
|
||||
)}
|
||||
</SettingsContainer>
|
||||
);
|
||||
}
|
||||
@@ -0,0 +1 @@
|
||||
export { default as SocialProvidersSettings } from './SocialProvidersSettings';
|
||||
@@ -0,0 +1,6 @@
|
||||
query getAuthUserProviders {
|
||||
authUserProviders {
|
||||
id
|
||||
providerId
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,6 @@
|
||||
mutation updateUserDisplayName($id: uuid!, $displayName: String!) {
|
||||
updateUser(pk_columns: { id: $id }, _set: { displayName: $displayName }) {
|
||||
id
|
||||
displayName
|
||||
}
|
||||
}
|
||||
@@ -1,5 +1,6 @@
|
||||
import { useDatabaseQuery } from '@/features/database/dataGrid/hooks/useDatabaseQuery';
|
||||
import { useCurrentWorkspaceAndProject } from '@/features/projects/common/hooks/useCurrentWorkspaceAndProject';
|
||||
import { useIsPlatform } from '@/features/projects/common/hooks/useIsPlatform';
|
||||
import { generateAppServiceUrl } from '@/features/projects/common/utils/generateAppServiceUrl';
|
||||
import { getToastStyleProps } from '@/utils/constants/settings';
|
||||
import { getHasuraAdminSecret } from '@/utils/env';
|
||||
@@ -17,6 +18,7 @@ export default function useRunSQL(
|
||||
migrationName: string,
|
||||
) {
|
||||
const { currentProject } = useCurrentWorkspaceAndProject();
|
||||
const isPlatform = useIsPlatform();
|
||||
|
||||
const [loading, setLoading] = useState(false);
|
||||
const [commandOk, setCommandOk] = useState(false);
|
||||
@@ -179,8 +181,34 @@ export default function useRunSQL(
|
||||
}
|
||||
};
|
||||
|
||||
const trackAll = async (objects: any[]): Promise<Response[]> => {
|
||||
const apiPath = isPlatform ? '/v1/metadata' : '/apis/migrate';
|
||||
const responses: Response[] = await Promise.all(
|
||||
objects.map((object) =>
|
||||
fetch(`${appUrl}${apiPath}`, {
|
||||
method: 'POST',
|
||||
headers: { 'x-hasura-admin-secret': adminSecret },
|
||||
body: JSON.stringify(object),
|
||||
}).then((response) => {
|
||||
if (!response.ok) {
|
||||
console.error('failed to track:', response);
|
||||
}
|
||||
return response;
|
||||
}),
|
||||
),
|
||||
).catch((error) => {
|
||||
console.error('Error in trackAll:', error);
|
||||
throw error;
|
||||
});
|
||||
|
||||
return responses;
|
||||
};
|
||||
|
||||
const updateMetadata = async (inputSQL: string) => {
|
||||
const entities = parseIdentifiersFromSQL(inputSQL);
|
||||
if (entities.length === 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
const tablesOrViewEntities = entities.filter(
|
||||
(entity) => entity.type !== 'function',
|
||||
@@ -189,47 +217,75 @@ export default function useRunSQL(
|
||||
(entity) => entity.type === 'function',
|
||||
);
|
||||
|
||||
const trackTablesOrViews = tablesOrViewEntities.map(({ name, schema }) => ({
|
||||
type: 'pg_track_table',
|
||||
args: {
|
||||
source: 'default',
|
||||
table: {
|
||||
name,
|
||||
schema,
|
||||
let trackTablesOrViews: any[] = [];
|
||||
let trackFunctions: any[] = [];
|
||||
if (isPlatform) {
|
||||
// use v2/query
|
||||
trackTablesOrViews = tablesOrViewEntities.map(({ name, schema }) => ({
|
||||
type: 'pg_track_table',
|
||||
args: {
|
||||
source: 'default',
|
||||
table: {
|
||||
name,
|
||||
schema,
|
||||
},
|
||||
},
|
||||
},
|
||||
}));
|
||||
|
||||
const trackFunctions = functionEntities.map(({ name, schema }) => ({
|
||||
type: 'pg_track_function',
|
||||
args: {
|
||||
source: 'default',
|
||||
function: {
|
||||
name,
|
||||
schema,
|
||||
configuration: {},
|
||||
}));
|
||||
trackFunctions = functionEntities.map(({ name, schema }) => ({
|
||||
type: 'pg_track_function',
|
||||
args: {
|
||||
source: 'default',
|
||||
function: {
|
||||
name,
|
||||
schema,
|
||||
configuration: {},
|
||||
},
|
||||
},
|
||||
},
|
||||
}));
|
||||
|
||||
const metaDataPayload = {
|
||||
source: 'default',
|
||||
type: 'bulk',
|
||||
args: [...trackTablesOrViews, ...trackFunctions],
|
||||
};
|
||||
}));
|
||||
} else {
|
||||
// use apis/migrate
|
||||
trackTablesOrViews = tablesOrViewEntities.map(({ name, schema }) => ({
|
||||
name: `add_existing_table_or_view_${schema}_${name}`,
|
||||
datasource: 'default',
|
||||
down: [],
|
||||
skip_execution: false,
|
||||
up: [
|
||||
{
|
||||
type: 'pg_track_table',
|
||||
args: {
|
||||
table: { name, schema },
|
||||
source: 'default',
|
||||
},
|
||||
},
|
||||
],
|
||||
}));
|
||||
trackFunctions = functionEntities.map(({ name, schema }) => ({
|
||||
name: `add_existing_function_or_view_${schema}_${name}`,
|
||||
datasource: 'default',
|
||||
down: [],
|
||||
skip_execution: false,
|
||||
up: [
|
||||
{
|
||||
type: 'pg_track_function',
|
||||
args: {
|
||||
function: { name, schema },
|
||||
source: 'default',
|
||||
},
|
||||
},
|
||||
],
|
||||
}));
|
||||
}
|
||||
|
||||
try {
|
||||
if (entities.length > 0) {
|
||||
const metadataApiResponse = await fetch(`${appUrl}/v1/metadata`, {
|
||||
method: 'POST',
|
||||
headers: { 'x-hasura-admin-secret': adminSecret },
|
||||
body: JSON.stringify(metaDataPayload),
|
||||
});
|
||||
|
||||
if (!metadataApiResponse.ok) {
|
||||
throw new Error('Metadata API call failed');
|
||||
}
|
||||
}
|
||||
await trackAll([...trackTablesOrViews, ...trackFunctions]).then(
|
||||
(responses) => {
|
||||
responses.forEach((response) => {
|
||||
if (!response.ok) {
|
||||
console.error('Error tracking table or view:', response);
|
||||
}
|
||||
});
|
||||
},
|
||||
);
|
||||
} catch (error) {
|
||||
toast.error('An error happened when calling the metadata API', {
|
||||
style: toastStyle.style,
|
||||
|
||||
@@ -47,7 +47,7 @@ export default function ApplicationPaused() {
|
||||
async function handleTriggerUnpausing() {
|
||||
await execPromiseWithErrorToast(
|
||||
async () => {
|
||||
unpauseApplication({ variables: { appId: currentProject.id } });
|
||||
await unpauseApplication({ variables: { appId: currentProject.id } });
|
||||
await refetchWorkspaceAndProject();
|
||||
},
|
||||
{
|
||||
|
||||
@@ -25,12 +25,12 @@ function Plan({ planName, price, setPlan, planId, selectedPlanId }: any) {
|
||||
return (
|
||||
<button
|
||||
type="button"
|
||||
className="grid items-center justify-between w-full grid-flow-col gap-2 px-1 my-4"
|
||||
className="my-4 grid w-full grid-flow-col items-center justify-between gap-2 px-1"
|
||||
onClick={setPlan}
|
||||
tabIndex={-1}
|
||||
>
|
||||
<div className="grid grid-flow-row gap-y-0.5">
|
||||
<div className="grid items-center justify-start grid-flow-col gap-2">
|
||||
<div className="grid grid-flow-col items-center justify-start gap-2">
|
||||
<Checkbox
|
||||
onChange={setPlan}
|
||||
checked={selectedPlanId === planId}
|
||||
@@ -40,7 +40,7 @@ function Plan({ planName, price, setPlan, planId, selectedPlanId }: any) {
|
||||
<Text
|
||||
variant="h3"
|
||||
component="p"
|
||||
className="self-center font-medium text-left"
|
||||
className="self-center text-left font-medium"
|
||||
>
|
||||
Upgrade to {planName}
|
||||
</Text>
|
||||
@@ -119,7 +119,7 @@ export function ChangePlanModalWithData({ app, plans, close }: any) {
|
||||
const handleUpdateAppPlan = async () => {
|
||||
await execPromiseWithErrorToast(
|
||||
async () => {
|
||||
updateApp({
|
||||
await updateApp({
|
||||
variables: {
|
||||
appId: app.id,
|
||||
app: {
|
||||
@@ -156,7 +156,7 @@ export function ChangePlanModalWithData({ app, plans, close }: any) {
|
||||
|
||||
if (pollingCurrentProject) {
|
||||
return (
|
||||
<Box className="w-full max-w-xl p-6 mx-auto text-left rounded-lg">
|
||||
<Box className="mx-auto w-full max-w-xl rounded-lg p-6 text-left">
|
||||
<div className="flex flex-col">
|
||||
<div className="mx-auto">
|
||||
<Image
|
||||
@@ -179,7 +179,7 @@ export function ChangePlanModalWithData({ app, plans, close }: any) {
|
||||
<Button
|
||||
variant="outlined"
|
||||
color="secondary"
|
||||
className="w-full max-w-sm mx-auto mt-4"
|
||||
className="mx-auto mt-4 w-full max-w-sm"
|
||||
onClick={() => {
|
||||
if (close) {
|
||||
close();
|
||||
@@ -196,7 +196,7 @@ export function ChangePlanModalWithData({ app, plans, close }: any) {
|
||||
}
|
||||
|
||||
return (
|
||||
<Box className="w-full max-w-xl p-6 text-left rounded-lg">
|
||||
<Box className="w-full max-w-xl rounded-lg p-6 text-left">
|
||||
<BaseDialog
|
||||
open={showPaymentModal}
|
||||
onClose={() => setShowPaymentModal(false)}
|
||||
@@ -241,7 +241,7 @@ export function ChangePlanModalWithData({ app, plans, close }: any) {
|
||||
))}
|
||||
</div>
|
||||
|
||||
<div className="grid grid-flow-row gap-2 mt-2">
|
||||
<div className="mt-2 grid grid-flow-row gap-2">
|
||||
<Button
|
||||
onClick={handleChangePlanClick}
|
||||
disabled={!selectedPlan}
|
||||
|
||||
@@ -47,7 +47,8 @@ export const validationSchema = Yup.object({
|
||||
initialDelaySeconds: Yup.number().required(),
|
||||
probePeriodSeconds: Yup.number().required(),
|
||||
})
|
||||
.nullable(),
|
||||
.nullable()
|
||||
.default(undefined),
|
||||
});
|
||||
|
||||
export type ServiceFormValues = Yup.InferType<typeof validationSchema>;
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
fragment EnvironmentVariable on ConfigEnvironmentVariable {
|
||||
fragment EnvironmentVariable on ConfigGlobalEnvironmentVariable {
|
||||
id: name
|
||||
name
|
||||
value
|
||||
|
||||
@@ -2,8 +2,10 @@ import { Container } from '@/components/layout/Container';
|
||||
import { RetryableErrorBoundary } from '@/components/presentational/RetryableErrorBoundary';
|
||||
import { AccountSettingsLayout } from '@/features/account/settings/components/AccountSettingsLayout';
|
||||
import { DeleteAccount } from '@/features/account/settings/components/DeleteAccount';
|
||||
import { DisplayNameSetting } from '@/features/account/settings/components/DisplayNameSetting';
|
||||
import { PasswordSettings } from '@/features/account/settings/components/PasswordSettings';
|
||||
import { PATSettings } from '@/features/account/settings/components/PATSettings';
|
||||
import { SocialProvidersSettings } from '@/features/account/settings/components/SocialProvidersSettings';
|
||||
import type { ReactElement } from 'react';
|
||||
|
||||
export default function AccountSettingsPage() {
|
||||
@@ -12,10 +14,18 @@ export default function AccountSettingsPage() {
|
||||
className="grid max-w-5xl grid-flow-row gap-8 bg-transparent"
|
||||
rootClassName="bg-transparent"
|
||||
>
|
||||
<RetryableErrorBoundary>
|
||||
<DisplayNameSetting />
|
||||
</RetryableErrorBoundary>
|
||||
|
||||
<RetryableErrorBoundary>
|
||||
<PasswordSettings />
|
||||
</RetryableErrorBoundary>
|
||||
|
||||
<RetryableErrorBoundary>
|
||||
<SocialProvidersSettings />
|
||||
</RetryableErrorBoundary>
|
||||
|
||||
<RetryableErrorBoundary>
|
||||
<PATSettings />
|
||||
</RetryableErrorBoundary>
|
||||
|
||||
94
dashboard/src/pages/email/verify.tsx
Normal file
94
dashboard/src/pages/email/verify.tsx
Normal file
@@ -0,0 +1,94 @@
|
||||
import { NavLink } from '@/components/common/NavLink';
|
||||
import { UnauthenticatedLayout } from '@/components/layout/UnauthenticatedLayout';
|
||||
import { Box } from '@/components/ui/v2/Box';
|
||||
import { Button } from '@/components/ui/v2/Button';
|
||||
import { Text } from '@/components/ui/v2/Text';
|
||||
import { getToastStyleProps } from '@/utils/constants/settings';
|
||||
import { useNhostClient } from '@nhost/nextjs';
|
||||
import { useRouter } from 'next/router';
|
||||
import { useEffect, useState, type ReactElement } from 'react';
|
||||
import { toast } from 'react-hot-toast';
|
||||
|
||||
export default function VerifyEmailPage() {
|
||||
const router = useRouter();
|
||||
const nhost = useNhostClient();
|
||||
|
||||
const {
|
||||
query: { email },
|
||||
} = router;
|
||||
|
||||
const [resendVerificationEmailLoading, setResendVerificationEmailLoading] =
|
||||
useState(false);
|
||||
|
||||
useEffect(() => {
|
||||
if (!email) {
|
||||
router.push('/signin');
|
||||
}
|
||||
}, [email, router]);
|
||||
|
||||
const resendVerificationEmail = async () => {
|
||||
setResendVerificationEmailLoading(true);
|
||||
|
||||
try {
|
||||
await nhost.auth.sendVerificationEmail({ email: email as string });
|
||||
|
||||
toast.success(
|
||||
`An new email has been sent to ${email}. Please follow the link to verify your email address and to
|
||||
complete your registration.`,
|
||||
getToastStyleProps(),
|
||||
);
|
||||
} catch {
|
||||
toast.error(
|
||||
'An error occurred while sending the verification email. Please try again.',
|
||||
getToastStyleProps(),
|
||||
);
|
||||
} finally {
|
||||
setResendVerificationEmailLoading(false);
|
||||
}
|
||||
};
|
||||
|
||||
return (
|
||||
<>
|
||||
<Text
|
||||
variant="h2"
|
||||
component="h1"
|
||||
className="text-center text-3.5xl font-semibold lg:text-4.5xl"
|
||||
>
|
||||
Verify your email
|
||||
</Text>
|
||||
|
||||
<Box className="grid grid-flow-row gap-4 rounded-md border bg-transparent p-6 lg:p-12">
|
||||
<div className="relative py-2">
|
||||
<Text color="secondary" className="text-center text-sm">
|
||||
Please check your inbox for the verification email. Follow the link
|
||||
to verify your email address and complete your registration.
|
||||
</Text>
|
||||
</div>
|
||||
<Button
|
||||
className="!bg-white !text-black disabled:!text-black disabled:!text-opacity-60"
|
||||
size="large"
|
||||
disabled={resendVerificationEmailLoading}
|
||||
loading={resendVerificationEmailLoading}
|
||||
type="button"
|
||||
onClick={resendVerificationEmail}
|
||||
>
|
||||
Resend verification email
|
||||
</Button>
|
||||
|
||||
<div className="flex justify-center">
|
||||
<NavLink href="/signin" color="white" className="font-medium">
|
||||
Sign In
|
||||
</NavLink>
|
||||
</div>
|
||||
</Box>
|
||||
</>
|
||||
);
|
||||
}
|
||||
|
||||
VerifyEmailPage.getLayout = function getLayout(page: ReactElement) {
|
||||
return (
|
||||
<UnauthenticatedLayout title="Verify your email">
|
||||
{page}
|
||||
</UnauthenticatedLayout>
|
||||
);
|
||||
};
|
||||
@@ -9,8 +9,8 @@ import { getToastStyleProps } from '@/utils/constants/settings';
|
||||
import { yupResolver } from '@hookform/resolvers/yup';
|
||||
import { styled } from '@mui/material';
|
||||
import { useSignInEmailPassword } from '@nhost/nextjs';
|
||||
import type { ReactElement } from 'react';
|
||||
import { useEffect } from 'react';
|
||||
import { useRouter } from 'next/router';
|
||||
import { useEffect, type ReactElement } from 'react';
|
||||
import { FormProvider, useForm } from 'react-hook-form';
|
||||
import { toast } from 'react-hot-toast';
|
||||
import * as Yup from 'yup';
|
||||
@@ -31,6 +31,7 @@ const StyledInput = styled(Input)({
|
||||
|
||||
export default function EmailSignUpPage() {
|
||||
const { signInEmailPassword, error } = useSignInEmailPassword();
|
||||
const router = useRouter();
|
||||
|
||||
const form = useForm<EmailSignUpFormValues>({
|
||||
reValidateMode: 'onSubmit',
|
||||
@@ -56,7 +57,14 @@ export default function EmailSignUpPage() {
|
||||
|
||||
async function handleSubmit({ email, password }: EmailSignUpFormValues) {
|
||||
try {
|
||||
await signInEmailPassword(email, password);
|
||||
const { needsEmailVerification } = await signInEmailPassword(
|
||||
email,
|
||||
password,
|
||||
);
|
||||
|
||||
if (needsEmailVerification) {
|
||||
router.push(`/email/verify?email=${email}`);
|
||||
}
|
||||
} catch {
|
||||
toast.error(
|
||||
'An error occurred while signing in. Please try again.',
|
||||
|
||||
@@ -12,6 +12,7 @@ import { nhost } from '@/utils/nhost';
|
||||
import { yupResolver } from '@hookform/resolvers/yup';
|
||||
import { styled } from '@mui/material';
|
||||
import { useSignUpEmailPassword } from '@nhost/nextjs';
|
||||
import { useRouter } from 'next/router';
|
||||
import type { ReactElement } from 'react';
|
||||
import { useEffect, useState } from 'react';
|
||||
import { FormProvider, useForm } from 'react-hook-form';
|
||||
@@ -36,6 +37,7 @@ const StyledInput = styled(Input)({
|
||||
export default function SignUpPage() {
|
||||
const { signUpEmailPassword, error } = useSignUpEmailPassword();
|
||||
const [loading, setLoading] = useState(false);
|
||||
const router = useRouter();
|
||||
|
||||
const form = useForm<SignUpFormValues>({
|
||||
reValidateMode: 'onSubmit',
|
||||
@@ -65,7 +67,15 @@ export default function SignUpPage() {
|
||||
displayName,
|
||||
}: SignUpFormValues) {
|
||||
try {
|
||||
await signUpEmailPassword(email, password, { displayName });
|
||||
const { needsEmailVerification } = await signUpEmailPassword(
|
||||
email,
|
||||
password,
|
||||
{ displayName },
|
||||
);
|
||||
|
||||
if (needsEmailVerification) {
|
||||
router.push(`/email/verify?email=${email}`);
|
||||
}
|
||||
} catch {
|
||||
toast.error(
|
||||
'An error occurred while signing up. Please try again.',
|
||||
|
||||
150
dashboard/src/utils/__generated__/graphql.ts
generated
150
dashboard/src/utils/__generated__/graphql.ts
generated
@@ -1272,22 +1272,47 @@ export type ConfigFunctionsUpdateInput = {
|
||||
export type ConfigGlobal = {
|
||||
__typename?: 'ConfigGlobal';
|
||||
/** User-defined environment variables that are spread over all services */
|
||||
environment?: Maybe<Array<ConfigEnvironmentVariable>>;
|
||||
environment?: Maybe<Array<ConfigGlobalEnvironmentVariable>>;
|
||||
};
|
||||
|
||||
export type ConfigGlobalComparisonExp = {
|
||||
_and?: InputMaybe<Array<ConfigGlobalComparisonExp>>;
|
||||
_not?: InputMaybe<ConfigGlobalComparisonExp>;
|
||||
_or?: InputMaybe<Array<ConfigGlobalComparisonExp>>;
|
||||
environment?: InputMaybe<ConfigEnvironmentVariableComparisonExp>;
|
||||
environment?: InputMaybe<ConfigGlobalEnvironmentVariableComparisonExp>;
|
||||
};
|
||||
|
||||
export type ConfigGlobalEnvironmentVariable = {
|
||||
__typename?: 'ConfigGlobalEnvironmentVariable';
|
||||
name: Scalars['String'];
|
||||
/** Value of the environment variable */
|
||||
value: Scalars['String'];
|
||||
};
|
||||
|
||||
export type ConfigGlobalEnvironmentVariableComparisonExp = {
|
||||
_and?: InputMaybe<Array<ConfigGlobalEnvironmentVariableComparisonExp>>;
|
||||
_not?: InputMaybe<ConfigGlobalEnvironmentVariableComparisonExp>;
|
||||
_or?: InputMaybe<Array<ConfigGlobalEnvironmentVariableComparisonExp>>;
|
||||
name?: InputMaybe<ConfigStringComparisonExp>;
|
||||
value?: InputMaybe<ConfigStringComparisonExp>;
|
||||
};
|
||||
|
||||
export type ConfigGlobalEnvironmentVariableInsertInput = {
|
||||
name: Scalars['String'];
|
||||
value: Scalars['String'];
|
||||
};
|
||||
|
||||
export type ConfigGlobalEnvironmentVariableUpdateInput = {
|
||||
name?: InputMaybe<Scalars['String']>;
|
||||
value?: InputMaybe<Scalars['String']>;
|
||||
};
|
||||
|
||||
export type ConfigGlobalInsertInput = {
|
||||
environment?: InputMaybe<Array<ConfigEnvironmentVariableInsertInput>>;
|
||||
environment?: InputMaybe<Array<ConfigGlobalEnvironmentVariableInsertInput>>;
|
||||
};
|
||||
|
||||
export type ConfigGlobalUpdateInput = {
|
||||
environment?: InputMaybe<Array<ConfigEnvironmentVariableUpdateInput>>;
|
||||
environment?: InputMaybe<Array<ConfigGlobalEnvironmentVariableUpdateInput>>;
|
||||
};
|
||||
|
||||
export type ConfigGrafana = {
|
||||
@@ -1428,6 +1453,8 @@ export type ConfigHasuraSettings = {
|
||||
enabledAPIs?: Maybe<Array<Scalars['ConfigHasuraAPIs']>>;
|
||||
/** HASURA_GRAPHQL_LIVE_QUERIES_MULTIPLEXED_REFETCH_INTERVAL */
|
||||
liveQueriesMultiplexedRefetchInterval?: Maybe<Scalars['ConfigUint32']>;
|
||||
/** HASURA_GRAPHQL_STRINGIFY_NUMERIC_TYPES */
|
||||
stringifyNumericTypes?: Maybe<Scalars['Boolean']>;
|
||||
};
|
||||
|
||||
export type ConfigHasuraSettingsComparisonExp = {
|
||||
@@ -1441,6 +1468,7 @@ export type ConfigHasuraSettingsComparisonExp = {
|
||||
enableRemoteSchemaPermissions?: InputMaybe<ConfigBooleanComparisonExp>;
|
||||
enabledAPIs?: InputMaybe<ConfigHasuraApIsComparisonExp>;
|
||||
liveQueriesMultiplexedRefetchInterval?: InputMaybe<ConfigUint32ComparisonExp>;
|
||||
stringifyNumericTypes?: InputMaybe<ConfigBooleanComparisonExp>;
|
||||
};
|
||||
|
||||
export type ConfigHasuraSettingsInsertInput = {
|
||||
@@ -1451,6 +1479,7 @@ export type ConfigHasuraSettingsInsertInput = {
|
||||
enableRemoteSchemaPermissions?: InputMaybe<Scalars['Boolean']>;
|
||||
enabledAPIs?: InputMaybe<Array<Scalars['ConfigHasuraAPIs']>>;
|
||||
liveQueriesMultiplexedRefetchInterval?: InputMaybe<Scalars['ConfigUint32']>;
|
||||
stringifyNumericTypes?: InputMaybe<Scalars['Boolean']>;
|
||||
};
|
||||
|
||||
export type ConfigHasuraSettingsUpdateInput = {
|
||||
@@ -1461,6 +1490,7 @@ export type ConfigHasuraSettingsUpdateInput = {
|
||||
enableRemoteSchemaPermissions?: InputMaybe<Scalars['Boolean']>;
|
||||
enabledAPIs?: InputMaybe<Array<Scalars['ConfigHasuraAPIs']>>;
|
||||
liveQueriesMultiplexedRefetchInterval?: InputMaybe<Scalars['ConfigUint32']>;
|
||||
stringifyNumericTypes?: InputMaybe<Scalars['Boolean']>;
|
||||
};
|
||||
|
||||
export type ConfigHasuraUpdateInput = {
|
||||
@@ -2510,6 +2540,14 @@ export type Metrics = {
|
||||
value: Scalars['float64'];
|
||||
};
|
||||
|
||||
export type StatsDailyLiveFreeApps = {
|
||||
__typename?: 'StatsDailyLiveFreeApps';
|
||||
avg: Scalars['Int'];
|
||||
max: Scalars['Int'];
|
||||
min: Scalars['Int'];
|
||||
raw: Array<Scalars['Int']>;
|
||||
};
|
||||
|
||||
export type StatsLiveApps = {
|
||||
__typename?: 'StatsLiveApps';
|
||||
appID: Array<Scalars['uuid']>;
|
||||
@@ -15821,6 +15859,12 @@ export type Query_Root = {
|
||||
softwareVersions: Array<Software_Versions>;
|
||||
/** fetch aggregated fields from the table: "software_versions" */
|
||||
softwareVersionsAggregate: Software_Versions_Aggregate;
|
||||
/**
|
||||
* Returns the per-day number of free live apps in the given time range, as well as the min, max and avg.
|
||||
*
|
||||
* Requests that returned a 4xx or 5xx status code are not counted as live traffic.
|
||||
*/
|
||||
statsDailyLiveFreeApps: StatsDailyLiveFreeApps;
|
||||
/**
|
||||
* Returns lists of apps that have some live traffic in the give time range.
|
||||
* From defaults to 24 hours ago and to defaults to now.
|
||||
@@ -16878,6 +16922,12 @@ export type Query_RootSoftwareVersionsAggregateArgs = {
|
||||
};
|
||||
|
||||
|
||||
export type Query_RootStatsDailyLiveFreeAppsArgs = {
|
||||
from?: InputMaybe<Scalars['Timestamp']>;
|
||||
to?: InputMaybe<Scalars['Timestamp']>;
|
||||
};
|
||||
|
||||
|
||||
export type Query_RootStatsLiveAppsArgs = {
|
||||
from?: InputMaybe<Scalars['Timestamp']>;
|
||||
to?: InputMaybe<Scalars['Timestamp']>;
|
||||
@@ -22439,6 +22489,11 @@ export type DeleteUserAccountMutationVariables = Exact<{
|
||||
|
||||
export type DeleteUserAccountMutation = { __typename?: 'mutation_root', deleteUser?: { __typename: 'users' } | null };
|
||||
|
||||
export type GetAuthUserProvidersQueryVariables = Exact<{ [key: string]: never; }>;
|
||||
|
||||
|
||||
export type GetAuthUserProvidersQuery = { __typename?: 'query_root', authUserProviders: Array<{ __typename?: 'authUserProviders', id: any, providerId: string }> };
|
||||
|
||||
export type GetPersonalAccessTokensQueryVariables = Exact<{ [key: string]: never; }>;
|
||||
|
||||
|
||||
@@ -22451,6 +22506,14 @@ export type DeletePersonalAccessTokenMutationVariables = Exact<{
|
||||
|
||||
export type DeletePersonalAccessTokenMutation = { __typename?: 'mutation_root', deletePersonalAccessToken?: { __typename?: 'authRefreshTokens', id: any, metadata?: any | null } | null };
|
||||
|
||||
export type UpdateUserDisplayNameMutationVariables = Exact<{
|
||||
id: Scalars['uuid'];
|
||||
displayName: Scalars['String'];
|
||||
}>;
|
||||
|
||||
|
||||
export type UpdateUserDisplayNameMutation = { __typename?: 'mutation_root', updateUser?: { __typename?: 'users', id: any, displayName: string } | null };
|
||||
|
||||
export type GetAiSettingsQueryVariables = Exact<{
|
||||
appId: Scalars['uuid'];
|
||||
}>;
|
||||
@@ -22629,7 +22692,7 @@ export type DnsLookupCnameQueryVariables = Exact<{
|
||||
|
||||
export type DnsLookupCnameQuery = { __typename?: 'query_root', dnsLookupCNAME: string };
|
||||
|
||||
export type EnvironmentVariableFragment = { __typename?: 'ConfigEnvironmentVariable', name: string, value: string, id: string };
|
||||
export type EnvironmentVariableFragment = { __typename?: 'ConfigGlobalEnvironmentVariable', name: string, value: string, id: string };
|
||||
|
||||
export type JwtSecretFragment = { __typename?: 'ConfigJWTSecret', issuer?: string | null, key?: string | null, type?: string | null, jwk_url?: any | null, header?: string | null, claims_namespace_path?: string | null, claims_namespace?: string | null, claims_format?: string | null, audience?: string | null, allowed_skew?: any | null };
|
||||
|
||||
@@ -22638,7 +22701,7 @@ export type GetEnvironmentVariablesQueryVariables = Exact<{
|
||||
}>;
|
||||
|
||||
|
||||
export type GetEnvironmentVariablesQuery = { __typename?: 'query_root', config?: { __typename: 'ConfigConfig', id: 'ConfigConfig', global?: { __typename?: 'ConfigGlobal', environment?: Array<{ __typename?: 'ConfigEnvironmentVariable', name: string, value: string, id: string }> | null } | null, hasura: { __typename?: 'ConfigHasura', adminSecret: string, webhookSecret: string, jwtSecrets?: Array<{ __typename?: 'ConfigJWTSecret', issuer?: string | null, key?: string | null, type?: string | null, jwk_url?: any | null, header?: string | null, claims_namespace_path?: string | null, claims_namespace?: string | null, claims_format?: string | null, audience?: string | null, allowed_skew?: any | null }> | null } } | null };
|
||||
export type GetEnvironmentVariablesQuery = { __typename?: 'query_root', config?: { __typename: 'ConfigConfig', id: 'ConfigConfig', global?: { __typename?: 'ConfigGlobal', environment?: Array<{ __typename?: 'ConfigGlobalEnvironmentVariable', name: string, value: string, id: string }> | null } | null, hasura: { __typename?: 'ConfigHasura', adminSecret: string, webhookSecret: string, jwtSecrets?: Array<{ __typename?: 'ConfigJWTSecret', issuer?: string | null, key?: string | null, type?: string | null, jwk_url?: any | null, header?: string | null, claims_namespace_path?: string | null, claims_namespace?: string | null, claims_format?: string | null, audience?: string | null, allowed_skew?: any | null }> | null } } | null };
|
||||
|
||||
export type PermissionVariableFragment = { __typename?: 'ConfigAuthsessionaccessTokenCustomClaims', key: string, value: string, id: string };
|
||||
|
||||
@@ -23227,7 +23290,7 @@ export const PrefetchNewAppWorkspaceFragmentDoc = gql`
|
||||
}
|
||||
`;
|
||||
export const EnvironmentVariableFragmentDoc = gql`
|
||||
fragment EnvironmentVariable on ConfigEnvironmentVariable {
|
||||
fragment EnvironmentVariable on ConfigGlobalEnvironmentVariable {
|
||||
id: name
|
||||
name
|
||||
value
|
||||
@@ -23484,6 +23547,44 @@ export function useDeleteUserAccountMutation(baseOptions?: Apollo.MutationHookOp
|
||||
export type DeleteUserAccountMutationHookResult = ReturnType<typeof useDeleteUserAccountMutation>;
|
||||
export type DeleteUserAccountMutationResult = Apollo.MutationResult<DeleteUserAccountMutation>;
|
||||
export type DeleteUserAccountMutationOptions = Apollo.BaseMutationOptions<DeleteUserAccountMutation, DeleteUserAccountMutationVariables>;
|
||||
export const GetAuthUserProvidersDocument = gql`
|
||||
query getAuthUserProviders {
|
||||
authUserProviders {
|
||||
id
|
||||
providerId
|
||||
}
|
||||
}
|
||||
`;
|
||||
|
||||
/**
|
||||
* __useGetAuthUserProvidersQuery__
|
||||
*
|
||||
* To run a query within a React component, call `useGetAuthUserProvidersQuery` and pass it any options that fit your needs.
|
||||
* When your component renders, `useGetAuthUserProvidersQuery` returns an object from Apollo Client that contains loading, error, and data properties
|
||||
* you can use to render your UI.
|
||||
*
|
||||
* @param baseOptions options that will be passed into the query, supported options are listed on: https://www.apollographql.com/docs/react/api/react-hooks/#options;
|
||||
*
|
||||
* @example
|
||||
* const { data, loading, error } = useGetAuthUserProvidersQuery({
|
||||
* variables: {
|
||||
* },
|
||||
* });
|
||||
*/
|
||||
export function useGetAuthUserProvidersQuery(baseOptions?: Apollo.QueryHookOptions<GetAuthUserProvidersQuery, GetAuthUserProvidersQueryVariables>) {
|
||||
const options = {...defaultOptions, ...baseOptions}
|
||||
return Apollo.useQuery<GetAuthUserProvidersQuery, GetAuthUserProvidersQueryVariables>(GetAuthUserProvidersDocument, options);
|
||||
}
|
||||
export function useGetAuthUserProvidersLazyQuery(baseOptions?: Apollo.LazyQueryHookOptions<GetAuthUserProvidersQuery, GetAuthUserProvidersQueryVariables>) {
|
||||
const options = {...defaultOptions, ...baseOptions}
|
||||
return Apollo.useLazyQuery<GetAuthUserProvidersQuery, GetAuthUserProvidersQueryVariables>(GetAuthUserProvidersDocument, options);
|
||||
}
|
||||
export type GetAuthUserProvidersQueryHookResult = ReturnType<typeof useGetAuthUserProvidersQuery>;
|
||||
export type GetAuthUserProvidersLazyQueryHookResult = ReturnType<typeof useGetAuthUserProvidersLazyQuery>;
|
||||
export type GetAuthUserProvidersQueryResult = Apollo.QueryResult<GetAuthUserProvidersQuery, GetAuthUserProvidersQueryVariables>;
|
||||
export function refetchGetAuthUserProvidersQuery(variables?: GetAuthUserProvidersQueryVariables) {
|
||||
return { query: GetAuthUserProvidersDocument, variables: variables }
|
||||
}
|
||||
export const GetPersonalAccessTokensDocument = gql`
|
||||
query GetPersonalAccessTokens {
|
||||
personalAccessTokens: authRefreshTokens(
|
||||
@@ -23561,6 +23662,41 @@ export function useDeletePersonalAccessTokenMutation(baseOptions?: Apollo.Mutati
|
||||
export type DeletePersonalAccessTokenMutationHookResult = ReturnType<typeof useDeletePersonalAccessTokenMutation>;
|
||||
export type DeletePersonalAccessTokenMutationResult = Apollo.MutationResult<DeletePersonalAccessTokenMutation>;
|
||||
export type DeletePersonalAccessTokenMutationOptions = Apollo.BaseMutationOptions<DeletePersonalAccessTokenMutation, DeletePersonalAccessTokenMutationVariables>;
|
||||
export const UpdateUserDisplayNameDocument = gql`
|
||||
mutation updateUserDisplayName($id: uuid!, $displayName: String!) {
|
||||
updateUser(pk_columns: {id: $id}, _set: {displayName: $displayName}) {
|
||||
id
|
||||
displayName
|
||||
}
|
||||
}
|
||||
`;
|
||||
export type UpdateUserDisplayNameMutationFn = Apollo.MutationFunction<UpdateUserDisplayNameMutation, UpdateUserDisplayNameMutationVariables>;
|
||||
|
||||
/**
|
||||
* __useUpdateUserDisplayNameMutation__
|
||||
*
|
||||
* To run a mutation, you first call `useUpdateUserDisplayNameMutation` within a React component and pass it any options that fit your needs.
|
||||
* When your component renders, `useUpdateUserDisplayNameMutation` 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 [updateUserDisplayNameMutation, { data, loading, error }] = useUpdateUserDisplayNameMutation({
|
||||
* variables: {
|
||||
* id: // value for 'id'
|
||||
* displayName: // value for 'displayName'
|
||||
* },
|
||||
* });
|
||||
*/
|
||||
export function useUpdateUserDisplayNameMutation(baseOptions?: Apollo.MutationHookOptions<UpdateUserDisplayNameMutation, UpdateUserDisplayNameMutationVariables>) {
|
||||
const options = {...defaultOptions, ...baseOptions}
|
||||
return Apollo.useMutation<UpdateUserDisplayNameMutation, UpdateUserDisplayNameMutationVariables>(UpdateUserDisplayNameDocument, options);
|
||||
}
|
||||
export type UpdateUserDisplayNameMutationHookResult = ReturnType<typeof useUpdateUserDisplayNameMutation>;
|
||||
export type UpdateUserDisplayNameMutationResult = Apollo.MutationResult<UpdateUserDisplayNameMutation>;
|
||||
export type UpdateUserDisplayNameMutationOptions = Apollo.BaseMutationOptions<UpdateUserDisplayNameMutation, UpdateUserDisplayNameMutationVariables>;
|
||||
export const GetAiSettingsDocument = gql`
|
||||
query GetAISettings($appId: uuid!) {
|
||||
config(appID: $appId, resolve: false) {
|
||||
|
||||
@@ -1,5 +1,28 @@
|
||||
# @nhost/docs
|
||||
|
||||
## 2.8.0
|
||||
|
||||
### Minor Changes
|
||||
|
||||
- 768ca17: chore: update dependencies
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- 9f2bf9e: chore: added hasura's authHook settings
|
||||
|
||||
## 2.7.2
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- 5c47e8e: feat: added hasura's stringifyNumericTypes setting
|
||||
|
||||
## 2.7.1
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- 6cb2b63: feat: added nhost run env documentation
|
||||
- 40bd3e4: fix: fixed wrong links in documentation
|
||||
|
||||
## 2.7.0
|
||||
|
||||
### Minor Changes
|
||||
|
||||
@@ -44,8 +44,22 @@ Below, you will find the official `CUE` schema and an example on how to configur
|
||||
|
||||
// HASURA_GRAPHQL_LIVE_QUERIES_MULTIPLEXED_REFETCH_INTERVAL
|
||||
liveQueriesMultiplexedRefetchInterval: uint32 | *1000
|
||||
|
||||
// HASURA_GRAPHQL_STRINGIFY_NUMERIC_TYPES
|
||||
stringifyNumericTypes: bool | *false
|
||||
}
|
||||
|
||||
authHook?: {
|
||||
// HASURA_GRAPHQL_AUTH_HOOK
|
||||
url: string
|
||||
|
||||
// HASURA_GRAPHQL_AUTH_HOOK_MODE
|
||||
mode: "GET"|*"POST"
|
||||
|
||||
// HASURA_GRAPHQL_AUTH_HOOK_SEND_REQUEST_BODY
|
||||
sendRequestBody: bool | *true
|
||||
}
|
||||
|
||||
logs: {
|
||||
// HASURA_GRAPHQL_LOG_LEVEL
|
||||
level: "debug" | "info" | "error" | *"warn"
|
||||
@@ -83,6 +97,7 @@ enableConsole = true
|
||||
enableRemoteSchemaPermissions = true
|
||||
enabledAPIs = ['metadata']
|
||||
liveQueriesMultiplexedRefetchInterval = 1000
|
||||
stringifyNumericTypes = false
|
||||
|
||||
[hasura.logs]
|
||||
level = 'warn'
|
||||
|
||||
@@ -86,4 +86,4 @@ await nhost.auth.sendVerificationEmail(
|
||||
</Tab>
|
||||
</Tabs>
|
||||
|
||||
<Tip>It is possible to customize these automatic emails, learn how to [here](/authentication/templates)</Tip>
|
||||
<Tip>It is possible to customize these automatic emails, learn how to [here](/guides/auth/email-templates)</Tip>
|
||||
|
||||
@@ -34,5 +34,5 @@ await nhost.auth.signIn(
|
||||
|
||||
<Tip>Users who have signed up with email and password can also sign in with a Magic Link</Tip>
|
||||
|
||||
<Tip>It is possible to customize the email with the Magic Link, learn how to [here](/authentication/templates)</Tip>
|
||||
<Tip>It is possible to customize the email with the Magic Link, learn how to [here](/guides/auth/email-templates)</Tip>
|
||||
|
||||
|
||||
@@ -19,7 +19,7 @@ You're allowed to:
|
||||
|
||||
## Roles
|
||||
|
||||
Each user has one **default role** and a list of **allowed roles**. These roles are used to resolve permissions for requests to [GraphQL](/graphql/permissions) and [Storage](/storage#permissions).
|
||||
Each user has one **default role** and a list of **allowed roles**. These roles are used to resolve permissions for requests to [GraphQL](/guides/api/permissions) and [Storage](/guides/storage/overview#permissions).
|
||||
|
||||
When the user makes a request, only one role is used to resolve permissions. The default role is used if no role is explicitly specified. Users can only make requests using the default role or one of the allowed roles.
|
||||
|
||||
|
||||
@@ -24,3 +24,65 @@ Based on the information above, if you want to connect directly to your service
|
||||
<Note>You can also use the environment variable `NHOST_RUN_SERVICE` passing comma-separated values. For instance, the equivalent environment variable for this example would be `NHOST_RUN_SERVICE=../mysvc/nhost-run-service.toml:mysvc,../mysvc/nhost-run-service.toml`</Note>
|
||||
|
||||
<Warning>The Nhost CLI doesn't build services so make sure you build any image that might be needed for running `nhost run --run-service...`</Warning>
|
||||
|
||||
# Quick Development
|
||||
|
||||
While developing your service, you may want to run it locally outside of the Nhost CLI to quickly iterate on it. To simplify this the Nhost CLI includes a command to generate an `.env` file based on your environment variables configuration and secrets. For instance, imagine a service with the following configuration:
|
||||
|
||||
<Tabs>
|
||||
<Tab title="run-service.toml">
|
||||
```toml
|
||||
[[environment]]
|
||||
name = 'HASURA_GRAPHQL_URL'
|
||||
value = 'http://hasura-service:8080/v1/graphql'
|
||||
|
||||
[[environment]]
|
||||
name = 'SOME_CONFIGURATION_PARAMETER'
|
||||
value = 'some-value'
|
||||
|
||||
[[environment]]
|
||||
name = 'SECRET_KEY'
|
||||
value = '{{ secrets.SECRET_KEY }}'
|
||||
```
|
||||
</Tab>
|
||||
|
||||
<Tab title="overlay">
|
||||
```json
|
||||
[
|
||||
{
|
||||
"value": {
|
||||
"name": "ENVIRONMENT",
|
||||
"value": "dev"
|
||||
},
|
||||
"op": "add",
|
||||
"path": "/environment/-"
|
||||
},
|
||||
{
|
||||
"value": "https://local.graphql.nhost.run/v1/graphql",
|
||||
"op": "replace",
|
||||
"path": "/environment/0/value"
|
||||
}
|
||||
]
|
||||
```
|
||||
</Tab>
|
||||
<Tab title=".secrets">
|
||||
```toml
|
||||
SECRET_KEY = '#asdasd;l;kq23\\n40-0as9d"$\\'
|
||||
```
|
||||
</Tab>
|
||||
</Tabs>
|
||||
|
||||
We can then generate an `env` file for our service with the folllowing command:
|
||||
|
||||
```
|
||||
$ nhost run env --config ../mysvc/nhost-run-service.toml --overlay-name local-dev > .env
|
||||
$ cat .env
|
||||
HASURA_GRAPHQL_URL="https://local.graphql.nhost.run/v1/graphql"
|
||||
SOME_CONFIGURATION_PARAMETER="some-value"
|
||||
SECRET_KEY="#asdasd;l;kq23\\n40-0as9d\"\$\\"
|
||||
ENVIRONMENT="dev"
|
||||
```
|
||||
|
||||
<Warning>
|
||||
Keep in mind you may need to use different configuration when attempting to connect to other services in the stack. For instance, in the example above we are using `http://hasura-service:8080/v1/graphql` to connect to hasura in production and in the CLI but when running the service in the host machine using the env file we are using an overlay to change the value to `https://local.graphql.nhost.run/v1/graphql`. Refer to the [network](networking) configuration for more details.
|
||||
</Warning>
|
||||
|
||||
@@ -1,11 +1,11 @@
|
||||
{
|
||||
"name": "@nhost/docs",
|
||||
"version": "2.7.0",
|
||||
"version": "2.8.0",
|
||||
"private": true,
|
||||
"scripts": {
|
||||
"start": "mintlify dev"
|
||||
},
|
||||
"devDependencies": {
|
||||
"mintlify": "^4.0.128"
|
||||
"mintlify": "^4.0.136"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,5 +1,27 @@
|
||||
# @nhost-examples/cli
|
||||
|
||||
## 0.3.0
|
||||
|
||||
### Minor Changes
|
||||
|
||||
- 768ca17: chore: update dependencies
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- @nhost/nhost-js@3.0.10
|
||||
|
||||
## 0.2.2
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- @nhost/nhost-js@3.0.10
|
||||
|
||||
## 0.2.1
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- @nhost/nhost-js@3.0.9
|
||||
|
||||
## 0.2.0
|
||||
|
||||
### Minor Changes
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@nhost-examples/cli",
|
||||
"version": "0.2.0",
|
||||
"version": "0.3.0",
|
||||
"main": "src/index.mjs",
|
||||
"private": true,
|
||||
"scripts": {
|
||||
|
||||
@@ -1,5 +1,36 @@
|
||||
# @nhost-examples/codegen-react-apollo
|
||||
|
||||
## 0.4.0
|
||||
|
||||
### Minor Changes
|
||||
|
||||
- 768ca17: chore: update dependencies
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [768ca17]
|
||||
- @nhost/react-apollo@11.0.0
|
||||
- @nhost/react@3.4.0
|
||||
|
||||
## 0.3.1
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [311374e]
|
||||
- @nhost/react@3.3.2
|
||||
- @nhost/react-apollo@10.0.2
|
||||
|
||||
## 0.3.0
|
||||
|
||||
### Minor Changes
|
||||
|
||||
- 7789469: chore: upgrade dependency `@graphql-codegen/cli` to `5.0.2` to address vulnerability
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- @nhost/react@3.3.1
|
||||
- @nhost/react-apollo@10.0.1
|
||||
|
||||
## 0.2.0
|
||||
|
||||
### Minor Changes
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@nhost-examples/codegen-react-apollo",
|
||||
"version": "0.2.0",
|
||||
"version": "0.4.0",
|
||||
"private": true,
|
||||
"scripts": {
|
||||
"codegen": "graphql-codegen",
|
||||
@@ -15,7 +15,7 @@
|
||||
]
|
||||
},
|
||||
"dependencies": {
|
||||
"@apollo/client": "^3.9.5",
|
||||
"@apollo/client": "^3.9.9",
|
||||
"@nhost/react": "workspace:^",
|
||||
"@nhost/react-apollo": "workspace:^",
|
||||
"clsx": "^1.2.1",
|
||||
@@ -24,18 +24,18 @@
|
||||
"react-dom": "^18.2.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@graphql-codegen/cli": "^2.16.5",
|
||||
"@graphql-codegen/cli": "^5.0.2",
|
||||
"@graphql-codegen/client-preset": "^1.3.0",
|
||||
"@graphql-typed-document-node/core": "^3.2.0",
|
||||
"@tailwindcss/forms": "^0.5.7",
|
||||
"@types/node": "^18.19.21",
|
||||
"@types/react": "^18.2.61",
|
||||
"@types/react-dom": "^18.2.19",
|
||||
"@types/node": "^18.19.28",
|
||||
"@types/react": "^18.2.73",
|
||||
"@types/react-dom": "^18.2.23",
|
||||
"@vitejs/plugin-react": "^3.1.0",
|
||||
"autoprefixer": "^10.4.17",
|
||||
"postcss": "^8.4.35",
|
||||
"tailwindcss": "^3.4.1",
|
||||
"autoprefixer": "^10.4.19",
|
||||
"postcss": "^8.4.38",
|
||||
"tailwindcss": "^3.4.3",
|
||||
"typescript": "^4.9.5",
|
||||
"vite": "^5.1.4"
|
||||
"vite": "^5.2.7"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,5 +1,33 @@
|
||||
# @nhost-examples/codegen-react-query
|
||||
|
||||
## 0.4.0
|
||||
|
||||
### Minor Changes
|
||||
|
||||
- 768ca17: chore: update dependencies
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [768ca17]
|
||||
- @nhost/react@3.4.0
|
||||
|
||||
## 0.3.1
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [311374e]
|
||||
- @nhost/react@3.3.2
|
||||
|
||||
## 0.3.0
|
||||
|
||||
### Minor Changes
|
||||
|
||||
- 7789469: chore: upgrade dependency `@graphql-codegen/cli` to `5.0.2` to address vulnerability
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- @nhost/react@3.3.1
|
||||
|
||||
## 0.2.0
|
||||
|
||||
### Minor Changes
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@nhost-examples/codegen-react-query",
|
||||
"version": "0.2.0",
|
||||
"version": "0.4.0",
|
||||
"private": true,
|
||||
"scripts": {
|
||||
"codegen": "graphql-codegen",
|
||||
@@ -25,18 +25,18 @@
|
||||
"react-dom": "^18.2.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@graphql-codegen/cli": "^2.16.5",
|
||||
"@graphql-codegen/cli": "^5.0.2",
|
||||
"@graphql-codegen/client-preset": "^1.3.0",
|
||||
"@graphql-typed-document-node/core": "^3.2.0",
|
||||
"@tailwindcss/forms": "^0.5.7",
|
||||
"@types/node": "^16.18.86",
|
||||
"@types/react": "^18.2.61",
|
||||
"@types/react-dom": "^18.2.19",
|
||||
"autoprefixer": "^10.4.17",
|
||||
"@types/node": "^16.18.93",
|
||||
"@types/react": "^18.2.73",
|
||||
"@types/react-dom": "^18.2.23",
|
||||
"autoprefixer": "^10.4.19",
|
||||
"eslint": "^8.57.0",
|
||||
"postcss": "^8.4.35",
|
||||
"tailwindcss": "^3.4.1",
|
||||
"postcss": "^8.4.38",
|
||||
"tailwindcss": "^3.4.3",
|
||||
"typescript": "^4.9.5",
|
||||
"vite": "^5.1.4"
|
||||
"vite": "^5.2.7"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,5 +1,36 @@
|
||||
# @nhost-examples/react-urql
|
||||
|
||||
## 0.3.0
|
||||
|
||||
### Minor Changes
|
||||
|
||||
- 768ca17: chore: update dependencies
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [768ca17]
|
||||
- @nhost/react-urql@8.0.0
|
||||
- @nhost/react@3.4.0
|
||||
|
||||
## 0.2.1
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [311374e]
|
||||
- @nhost/react@3.3.2
|
||||
- @nhost/react-urql@7.0.2
|
||||
|
||||
## 0.2.0
|
||||
|
||||
### Minor Changes
|
||||
|
||||
- 7789469: chore: upgrade dependency `@graphql-codegen/cli` to `5.0.2` to address vulnerability
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- @nhost/react@3.3.1
|
||||
- @nhost/react-urql@7.0.1
|
||||
|
||||
## 0.1.0
|
||||
|
||||
### Minor Changes
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
{
|
||||
"name": "@nhost-examples/codegen-react-urql",
|
||||
"private": true,
|
||||
"version": "0.1.0",
|
||||
"version": "0.3.0",
|
||||
"scripts": {
|
||||
"dev": "vite",
|
||||
"build": "tsc && vite build",
|
||||
@@ -18,18 +18,18 @@
|
||||
"urql": "^3.0.4"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@graphql-codegen/cli": "^2.16.5",
|
||||
"@graphql-codegen/cli": "^5.0.2",
|
||||
"@graphql-codegen/client-preset": "^1.3.0",
|
||||
"@graphql-typed-document-node/core": "^3.2.0",
|
||||
"@tailwindcss/forms": "^0.5.7",
|
||||
"@types/node": "^16.18.86",
|
||||
"@types/react": "^18.2.61",
|
||||
"@types/react-dom": "^18.2.19",
|
||||
"@types/node": "^16.18.93",
|
||||
"@types/react": "^18.2.73",
|
||||
"@types/react-dom": "^18.2.23",
|
||||
"@vitejs/plugin-react": "^3.1.0",
|
||||
"autoprefixer": "^10.4.17",
|
||||
"postcss": "^8.4.35",
|
||||
"tailwindcss": "^3.4.1",
|
||||
"autoprefixer": "^10.4.19",
|
||||
"postcss": "^8.4.38",
|
||||
"tailwindcss": "^3.4.3",
|
||||
"typescript": "^4.9.5",
|
||||
"vite": "^5.1.4"
|
||||
"vite": "^5.2.7"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,5 +1,17 @@
|
||||
# @nhost-examples/docker-compose
|
||||
|
||||
## 0.4.0
|
||||
|
||||
### Minor Changes
|
||||
|
||||
- 768ca17: chore: update dependencies
|
||||
|
||||
## 0.3.0
|
||||
|
||||
### Minor Changes
|
||||
|
||||
- e40a452: chore: clarification on greyed-out options in the dashboard when self-hosting
|
||||
|
||||
## 0.2.0
|
||||
|
||||
### Minor Changes
|
||||
|
||||
@@ -2,6 +2,8 @@
|
||||
|
||||
Here is an example on how to reproduce the Nhost stack from a docker-compose file.
|
||||
|
||||
NOTE: You may notice that some options in the dashboard are greyed-out. These include additional services like CI integration, configuration management, etc., offered by the Nhost Cloud and therefore are not accessible when self-hosting.
|
||||
|
||||
## Configuration
|
||||
|
||||
```sh
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@nhost-examples/docker-compose",
|
||||
"version": "0.2.0",
|
||||
"version": "0.4.0",
|
||||
"private": true,
|
||||
"scripts": {
|
||||
"e2e": "vitest run"
|
||||
|
||||
@@ -1,5 +1,27 @@
|
||||
# @nhost-examples/multi-tenant-one-to-many
|
||||
|
||||
## 2.2.0
|
||||
|
||||
### Minor Changes
|
||||
|
||||
- 768ca17: chore: update dependencies
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- @nhost/nhost-js@3.0.10
|
||||
|
||||
## 2.1.2
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- @nhost/nhost-js@3.0.10
|
||||
|
||||
## 2.1.1
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- @nhost/nhost-js@3.0.9
|
||||
|
||||
## 2.1.0
|
||||
|
||||
### Minor Changes
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
{
|
||||
"name": "@nhost-examples/multi-tenant-one-to-many",
|
||||
"private": true,
|
||||
"version": "2.1.0",
|
||||
"version": "2.2.0",
|
||||
"description": "",
|
||||
"main": "index.js",
|
||||
"scripts": {},
|
||||
@@ -10,7 +10,7 @@
|
||||
"license": "ISC",
|
||||
"devDependencies": {
|
||||
"@types/express": "^4.17.21",
|
||||
"express": "^4.18.3",
|
||||
"express": "^4.19.2",
|
||||
"typescript": "^4.9.5"
|
||||
},
|
||||
"dependencies": {
|
||||
|
||||
@@ -1,5 +1,35 @@
|
||||
# @nhost-examples/nextjs
|
||||
|
||||
## 0.3.0
|
||||
|
||||
### Minor Changes
|
||||
|
||||
- 768ca17: chore: update dependencies
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [768ca17]
|
||||
- @nhost/react-apollo@11.0.0
|
||||
- @nhost/react@3.4.0
|
||||
- @nhost/nextjs@2.1.9
|
||||
|
||||
## 0.2.2
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [311374e]
|
||||
- @nhost/react@3.3.2
|
||||
- @nhost/react-apollo@10.0.2
|
||||
- @nhost/nextjs@2.1.8
|
||||
|
||||
## 0.2.1
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- @nhost/react@3.3.1
|
||||
- @nhost/react-apollo@10.0.1
|
||||
- @nhost/nextjs@2.1.7
|
||||
|
||||
## 0.2.0
|
||||
|
||||
### Minor Changes
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@nhost-examples/nextjs",
|
||||
"version": "0.2.0",
|
||||
"version": "0.3.0",
|
||||
"private": true,
|
||||
"scripts": {
|
||||
"dev": "next dev",
|
||||
@@ -15,7 +15,7 @@
|
||||
"verify:fix": "run-p prettier:fix lint:fix"
|
||||
},
|
||||
"dependencies": {
|
||||
"@apollo/client": "^3.9.5",
|
||||
"@apollo/client": "^3.9.9",
|
||||
"@mantine/core": "^4.2.12",
|
||||
"@mantine/hooks": "^4.2.12",
|
||||
"@mantine/next": "^4.2.12",
|
||||
@@ -24,15 +24,15 @@
|
||||
"@nhost/react": "workspace:^",
|
||||
"@nhost/react-apollo": "workspace:^",
|
||||
"graphql": "16.8.1",
|
||||
"next": "^14.1.0",
|
||||
"next": "^14.1.4",
|
||||
"react": "18.2.0",
|
||||
"react-dom": "18.2.0",
|
||||
"react-icons": "^4.12.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@next/bundle-analyzer": "^12.3.4",
|
||||
"@types/node": "^16.18.86",
|
||||
"@types/react": "^18.2.61",
|
||||
"@types/node": "^16.18.93",
|
||||
"@types/react": "^18.2.73",
|
||||
"@xstate/inspect": "^0.6.5",
|
||||
"eslint-config-next": "12.0.10",
|
||||
"typescript": "^4.9.5",
|
||||
|
||||
@@ -1,5 +1,27 @@
|
||||
# @nhost-examples/node-storage
|
||||
|
||||
## 0.2.0
|
||||
|
||||
### Minor Changes
|
||||
|
||||
- 768ca17: chore: update dependencies
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- @nhost/nhost-js@3.0.10
|
||||
|
||||
## 0.1.2
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- @nhost/nhost-js@3.0.10
|
||||
|
||||
## 0.1.1
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- @nhost/nhost-js@3.0.9
|
||||
|
||||
## 0.1.0
|
||||
|
||||
### Minor Changes
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@nhost-examples/node-storage",
|
||||
"version": "0.1.0",
|
||||
"version": "0.2.0",
|
||||
"private": true,
|
||||
"description": "This is an example of how to use the Storage with Node.js",
|
||||
"main": "src/index.mjs",
|
||||
@@ -19,7 +19,7 @@
|
||||
"uuid": "^9.0.1"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@types/node": "^18.19.21",
|
||||
"@types/node": "^18.19.28",
|
||||
"@types/uuid": "^9.0.8"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
module.exports = {
|
||||
extends: ['../../../config/.eslintrc.js', 'plugin:@next/next/recommended'],
|
||||
rules: {
|
||||
'react/react-in-jsx-scope': 'off'
|
||||
'react/react-in-jsx-scope': 'off',
|
||||
'@next/next/no-server-import-in-page': 'off'
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,5 +1,27 @@
|
||||
# @nhost-examples/nextjs-server-components
|
||||
|
||||
## 0.4.0
|
||||
|
||||
### Minor Changes
|
||||
|
||||
- 768ca17: chore: update dependencies
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- @nhost/nhost-js@3.0.10
|
||||
|
||||
## 0.3.2
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- @nhost/nhost-js@3.0.10
|
||||
|
||||
## 0.3.1
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- @nhost/nhost-js@3.0.9
|
||||
|
||||
## 0.3.0
|
||||
|
||||
### Minor Changes
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@nhost-examples/nextjs-server-components",
|
||||
"version": "0.3.0",
|
||||
"version": "0.4.0",
|
||||
"private": true,
|
||||
"scripts": {
|
||||
"dev": "next dev",
|
||||
@@ -9,7 +9,7 @@
|
||||
"lint": "next lint"
|
||||
},
|
||||
"dependencies": {
|
||||
"@apollo/client": "^3.9.5",
|
||||
"@apollo/client": "^3.9.9",
|
||||
"@nhost/nhost-js": "workspace:^",
|
||||
"autoprefixer": "10.4.15",
|
||||
"cookies-next": "^3.0.0",
|
||||
@@ -18,8 +18,8 @@
|
||||
"form-data": "^4.0.0",
|
||||
"graphql": "16.8.1",
|
||||
"js-cookie": "^3.0.5",
|
||||
"next": "^14.1.0",
|
||||
"postcss": "^8.4.35",
|
||||
"next": "^14.1.4",
|
||||
"postcss": "^8.4.38",
|
||||
"react": "^18.2.0",
|
||||
"react-dom": "^18.2.0",
|
||||
"tailwind-merge": "^1.14.0",
|
||||
@@ -30,7 +30,7 @@
|
||||
"devDependencies": {
|
||||
"@types/js-cookie": "^3.0.6",
|
||||
"@types/node": "20.5.6",
|
||||
"@types/react": "^18.2.61",
|
||||
"@types/react-dom": "^18.2.19"
|
||||
"@types/react": "^18.2.73",
|
||||
"@types/react-dom": "^18.2.23"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,6 +1,4 @@
|
||||
import { manageAuthSession } from '@utils/nhost'
|
||||
|
||||
// eslint-disable-next-line @next/next/no-server-import-in-page
|
||||
import { NextRequest, NextResponse } from 'next/server'
|
||||
|
||||
export async function middleware(request: NextRequest) {
|
||||
|
||||
@@ -1,9 +1,8 @@
|
||||
import { getNhost } from '@utils/nhost'
|
||||
import { redirect } from 'next/navigation'
|
||||
|
||||
const withAuthAsync =
|
||||
<P extends {}>(Component: React.FunctionComponent<P>) =>
|
||||
async (props: P) => {
|
||||
const withAuthAsync = <P extends {}>(Component: React.FunctionComponent<P>) => {
|
||||
const WrappedComponent = async (props: P) => {
|
||||
const nhost = await getNhost()
|
||||
const session = nhost.auth.getSession()
|
||||
|
||||
@@ -13,5 +12,11 @@ const withAuthAsync =
|
||||
|
||||
return <Component {...props} />
|
||||
}
|
||||
WrappedComponent.displayName = `withAuthAsync(${
|
||||
Component.displayName || Component.name || 'Component'
|
||||
})`
|
||||
|
||||
return WrappedComponent
|
||||
}
|
||||
|
||||
export default withAuthAsync
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
import { AuthErrorPayload, NhostClient, NhostSession } from '@nhost/nhost-js'
|
||||
import { cookies } from 'next/headers'
|
||||
|
||||
// eslint-disable-next-line @next/next/no-server-import-in-page
|
||||
import { NextRequest, NextResponse } from 'next/server'
|
||||
import { type StateFrom } from 'xstate/lib/types'
|
||||
import { waitFor } from 'xstate/lib/waitFor'
|
||||
|
||||
@@ -1,5 +1,10 @@
|
||||
---
|
||||
|
||||
## 0.4.0
|
||||
### Minor Changes
|
||||
|
||||
- 768ca17: chore: update dependencies
|
||||
|
||||
## 0.3.0
|
||||
### Minor Changes
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@nhost-examples/sveltekit",
|
||||
"version": "0.3.0",
|
||||
"version": "0.4.0",
|
||||
"private": true,
|
||||
"scripts": {
|
||||
"dev": "vite dev",
|
||||
@@ -16,22 +16,22 @@
|
||||
},
|
||||
"devDependencies": {
|
||||
"@nhost/nhost-js": "2.2.18",
|
||||
"@playwright/test": "^1.42.0",
|
||||
"@playwright/test": "^1.42.1",
|
||||
"@sveltejs/adapter-auto": "^2.1.1",
|
||||
"@sveltejs/kit": "^1.30.4",
|
||||
"@types/js-cookie": "^3.0.6",
|
||||
"autoprefixer": "^10.4.17",
|
||||
"autoprefixer": "^10.4.19",
|
||||
"eslint": "^8.57.0",
|
||||
"eslint-config-prettier": "^8.10.0",
|
||||
"eslint-plugin-svelte": "^2.35.1",
|
||||
"postcss": "^8.4.35",
|
||||
"postcss": "^8.4.38",
|
||||
"prettier": "^2.8.8",
|
||||
"prettier-plugin-svelte": "^2.10.1",
|
||||
"svelte": "^3.59.2",
|
||||
"svelte-check": "^3.6.6",
|
||||
"tailwindcss": "^3.4.1",
|
||||
"typescript": "^5.3.3",
|
||||
"vite": "^5.1.4",
|
||||
"svelte-check": "^3.6.8",
|
||||
"tailwindcss": "^3.4.3",
|
||||
"typescript": "^5.4.3",
|
||||
"vite": "^5.2.7",
|
||||
"vitest": "^0.25.8"
|
||||
},
|
||||
"type": "module",
|
||||
|
||||
@@ -1,5 +1,51 @@
|
||||
# @nhost-examples/react-apollo
|
||||
|
||||
## 0.8.0
|
||||
|
||||
### Minor Changes
|
||||
|
||||
- 768ca17: chore: update dependencies
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- 863b37d: chore: bump hasura-auth
|
||||
- Updated dependencies [768ca17]
|
||||
- @nhost/react-apollo@11.0.0
|
||||
- @nhost/react@3.4.0
|
||||
|
||||
## 0.7.0
|
||||
|
||||
### Minor Changes
|
||||
|
||||
- 311374e: feat: add example of how to connect a social auth provider to an existing account
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [311374e]
|
||||
- @nhost/react@3.3.2
|
||||
- @nhost/react-apollo@10.0.2
|
||||
|
||||
## 0.6.0
|
||||
|
||||
### Minor Changes
|
||||
|
||||
- 7789469: chore: upgrade dependency `@graphql-codegen/cli` to `5.0.2` to address vulnerability
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- @nhost/react@3.3.1
|
||||
- @nhost/react-apollo@10.0.1
|
||||
|
||||
## 0.5.0
|
||||
|
||||
### Minor Changes
|
||||
|
||||
- 08a7dd9: feat: add example workaround to the reset password ticket expired issue
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- f0a994a: fix: update allowedUrls and redirectTo to point to the profile page
|
||||
|
||||
## 0.4.1
|
||||
|
||||
### Patch Changes
|
||||
|
||||
@@ -8,7 +8,7 @@
|
||||
<h2>Verify Email</h2>
|
||||
<p>Use this link to verify your email:</p>
|
||||
<p>
|
||||
<a href="${link}"> Verify Email </a>
|
||||
<a href="${clientUrl}/verify?ticket=${ticket}&redirectTo=${redirectTo}&type=emailVerify"> Verify Email </a>
|
||||
</p>
|
||||
</body>
|
||||
</html>
|
||||
|
||||
@@ -8,7 +8,7 @@
|
||||
<h2>Reset Password</h2>
|
||||
<p>Use this link to reset your password:</p>
|
||||
<p>
|
||||
<a href="${link}"> Reset password </a>
|
||||
<a href="${clientUrl}/verify?ticket=${ticket}&redirectTo=${redirectTo}&type=emailVerify"> Reset password </a>
|
||||
</p>
|
||||
</body>
|
||||
</html>
|
||||
|
||||
@@ -1,14 +1,18 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="utf-8" />
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<h2>Magic Link</h2>
|
||||
<p>Use this link to securely sign in:</p>
|
||||
<p>
|
||||
<a href="${link}"> Sign In </a>
|
||||
</p>
|
||||
</body>
|
||||
</html>
|
||||
<head>
|
||||
<meta charset="utf-8" />
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<h2>Magic Link</h2>
|
||||
<p>Use this link to securely sign in:</p>
|
||||
<p>
|
||||
<a href="${link}">
|
||||
Verify Email
|
||||
</a>
|
||||
</p>
|
||||
</body>
|
||||
|
||||
</html>
|
||||
@@ -46,3 +46,13 @@ object_relationships:
|
||||
- name: user
|
||||
using:
|
||||
foreign_key_constraint_on: user_id
|
||||
select_permissions:
|
||||
- role: user
|
||||
permission:
|
||||
columns:
|
||||
- id
|
||||
- provider_id
|
||||
filter:
|
||||
user_id:
|
||||
_eq: X-Hasura-User-Id
|
||||
comment: ""
|
||||
|
||||
@@ -16,6 +16,7 @@ enableAllowList = false
|
||||
enableConsole = true
|
||||
enableRemoteSchemaPermissions = false
|
||||
enabledAPIs = ['metadata', 'graphql', 'pgdump', 'config']
|
||||
liveQueriesMultiplexedRefetchInterval = 1000
|
||||
|
||||
[hasura.logs]
|
||||
level = 'warn'
|
||||
@@ -28,17 +29,18 @@ httpPoolSize = 100
|
||||
version = 18
|
||||
|
||||
[auth]
|
||||
version = '0.26.0'
|
||||
version = '0.28.0-beta002'
|
||||
|
||||
[auth.elevatedPrivileges]
|
||||
mode = 'required'
|
||||
|
||||
[auth.redirections]
|
||||
clientUrl = 'https://react-apollo.example.nhost.io/'
|
||||
allowedUrls = ['https://react-apollo.example.nhost.io/profile', 'https://vue-apollo.example.nhost.io/profile', 'https://*.vercel.app','http://localhost:3000']
|
||||
allowedUrls = ['https://react-apollo.example.nhost.io', 'https://react-apollo.example.nhost.io/profile', 'https://vue-apollo.example.nhost.io', 'https://vue-apollo.example.nhost.io/profile', 'https://*.vercel.app', 'http://localhost:3000', 'http://localhost:3000/profile', 'http://localhost:5173', 'http://localhost:5173/profile']
|
||||
|
||||
[auth.signUp]
|
||||
enabled = true
|
||||
disableNewUsers = false
|
||||
|
||||
[auth.user]
|
||||
[auth.user.roles]
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
{
|
||||
"name": "@nhost-examples/react-apollo",
|
||||
"version": "0.4.1",
|
||||
"version": "0.8.0",
|
||||
"private": true,
|
||||
"dependencies": {
|
||||
"@apollo/client": "^3.9.5",
|
||||
"@apollo/client": "^3.9.9",
|
||||
"@mantine/core": "^4.2.12",
|
||||
"@mantine/dropzone": "^4.2.12",
|
||||
"@mantine/hooks": "^4.2.12",
|
||||
@@ -15,8 +15,8 @@
|
||||
"react": "^18.2.0",
|
||||
"react-dom": "^18.2.0",
|
||||
"react-icons": "^4.12.0",
|
||||
"react-router": "^6.22.2",
|
||||
"react-router-dom": "^6.22.2",
|
||||
"react-router": "^6.22.3",
|
||||
"react-router-dom": "^6.22.3",
|
||||
"tabler-icons-react": "^1.56.0"
|
||||
},
|
||||
"scripts": {
|
||||
@@ -50,12 +50,12 @@
|
||||
},
|
||||
"devDependencies": {
|
||||
"@faker-js/faker": "^7.6.0",
|
||||
"@graphql-codegen/cli": "^2.16.5",
|
||||
"@graphql-codegen/cli": "^5.0.2",
|
||||
"@nuintun/qrcode": "^3.4.0",
|
||||
"@playwright/test": "1.31.0",
|
||||
"@types/pngjs": "^6.0.4",
|
||||
"@types/react": "^18.2.61",
|
||||
"@types/react-dom": "^18.2.19",
|
||||
"@types/react": "^18.2.73",
|
||||
"@types/react-dom": "^18.2.23",
|
||||
"@types/totp-generator": "^0.0.4",
|
||||
"@vitejs/plugin-react": "^3.1.0",
|
||||
"@xstate/inspect": "^0.6.5",
|
||||
@@ -64,7 +64,7 @@
|
||||
"pngjs": "^7.0.0",
|
||||
"totp-generator": "^0.0.13",
|
||||
"typescript": "^4.9.5",
|
||||
"vite": "^5.1.4",
|
||||
"vite": "^5.2.7",
|
||||
"ws": "^8.16.0",
|
||||
"xstate": "^4.38.3"
|
||||
}
|
||||
|
||||
@@ -16,6 +16,7 @@ import { StoragePage } from './Storage'
|
||||
|
||||
import './App.css?inline'
|
||||
import { NotesPage } from './components/notes'
|
||||
import VerifyPage from './Verify'
|
||||
const title = 'Nhost with React and Apollo'
|
||||
|
||||
function App() {
|
||||
@@ -70,6 +71,7 @@ function App() {
|
||||
</AuthGate>
|
||||
}
|
||||
/>
|
||||
<Route path="/verify" element={<VerifyPage />} />
|
||||
<Route path="/about" element={<AboutPage />} />
|
||||
<Route
|
||||
path="/sign-in/*"
|
||||
|
||||
34
examples/react-apollo/src/Verify.tsx
Normal file
34
examples/react-apollo/src/Verify.tsx
Normal file
@@ -0,0 +1,34 @@
|
||||
import { useSearchParams } from 'react-router-dom'
|
||||
import { useEffect, useState } from 'react'
|
||||
import { useNhostClient } from '@nhost/react'
|
||||
import { Container } from '@mantine/core'
|
||||
|
||||
const VerifyPage: React.FC = () => {
|
||||
const nhost = useNhostClient()
|
||||
const [loading, setLoading] = useState(false)
|
||||
const [searchParams] = useSearchParams()
|
||||
|
||||
useEffect(() => {
|
||||
const ticket = searchParams.get('ticket')
|
||||
const redirectTo = searchParams.get('redirectTo')
|
||||
const type = searchParams.get('type')
|
||||
|
||||
if (ticket && redirectTo && type) {
|
||||
window.location.href = `${nhost.auth.url}/verify?ticket=${ticket}&type=${type}&redirectTo=${redirectTo}`
|
||||
}
|
||||
|
||||
setLoading(false)
|
||||
}, [searchParams, nhost?.auth?.url])
|
||||
|
||||
if (loading) {
|
||||
return null
|
||||
}
|
||||
|
||||
return (
|
||||
<Container>
|
||||
<span>Failed to authenticate with magick link</span>
|
||||
</Container>
|
||||
)
|
||||
}
|
||||
|
||||
export default VerifyPage
|
||||
@@ -6,7 +6,7 @@ import AuthLink from './AuthLink'
|
||||
|
||||
export default function OauthLinks() {
|
||||
const { github, google, apple, linkedin } = useProviderLink({
|
||||
redirectTo: window.location.origin
|
||||
redirectTo: `${window.location.origin}/profile`
|
||||
})
|
||||
|
||||
return (
|
||||
|
||||
@@ -201,6 +201,73 @@ export type AuthRefreshTokensStreamCursorValueInput = {
|
||||
userId?: InputMaybe<Scalars['uuid']>;
|
||||
};
|
||||
|
||||
/** Active providers for a given user. Don't modify its structure as Hasura Auth relies on it to function properly. */
|
||||
export type AuthUserProviders = {
|
||||
__typename?: 'authUserProviders';
|
||||
id: Scalars['uuid'];
|
||||
providerId: Scalars['String'];
|
||||
/** An object relationship */
|
||||
user: Users;
|
||||
};
|
||||
|
||||
/** order by aggregate values of table "auth.user_providers" */
|
||||
export type AuthUserProvidersAggregateOrderBy = {
|
||||
count?: InputMaybe<OrderBy>;
|
||||
max?: InputMaybe<AuthUserProvidersMaxOrderBy>;
|
||||
min?: InputMaybe<AuthUserProvidersMinOrderBy>;
|
||||
};
|
||||
|
||||
/** Boolean expression to filter rows from the table "auth.user_providers". All fields are combined with a logical 'AND'. */
|
||||
export type AuthUserProvidersBoolExp = {
|
||||
_and?: InputMaybe<Array<AuthUserProvidersBoolExp>>;
|
||||
_not?: InputMaybe<AuthUserProvidersBoolExp>;
|
||||
_or?: InputMaybe<Array<AuthUserProvidersBoolExp>>;
|
||||
id?: InputMaybe<UuidComparisonExp>;
|
||||
providerId?: InputMaybe<StringComparisonExp>;
|
||||
user?: InputMaybe<UsersBoolExp>;
|
||||
};
|
||||
|
||||
/** order by max() on columns of table "auth.user_providers" */
|
||||
export type AuthUserProvidersMaxOrderBy = {
|
||||
id?: InputMaybe<OrderBy>;
|
||||
providerId?: InputMaybe<OrderBy>;
|
||||
};
|
||||
|
||||
/** order by min() on columns of table "auth.user_providers" */
|
||||
export type AuthUserProvidersMinOrderBy = {
|
||||
id?: InputMaybe<OrderBy>;
|
||||
providerId?: InputMaybe<OrderBy>;
|
||||
};
|
||||
|
||||
/** Ordering options when selecting data from "auth.user_providers". */
|
||||
export type AuthUserProvidersOrderBy = {
|
||||
id?: InputMaybe<OrderBy>;
|
||||
providerId?: InputMaybe<OrderBy>;
|
||||
user?: InputMaybe<UsersOrderBy>;
|
||||
};
|
||||
|
||||
/** select columns of table "auth.user_providers" */
|
||||
export enum AuthUserProvidersSelectColumn {
|
||||
/** column name */
|
||||
Id = 'id',
|
||||
/** column name */
|
||||
ProviderId = 'providerId'
|
||||
}
|
||||
|
||||
/** Streaming cursor of the table "authUserProviders" */
|
||||
export type AuthUserProvidersStreamCursorInput = {
|
||||
/** Stream column input with initial value */
|
||||
initial_value: AuthUserProvidersStreamCursorValueInput;
|
||||
/** cursor ordering */
|
||||
ordering?: InputMaybe<CursorOrdering>;
|
||||
};
|
||||
|
||||
/** Initial value of the column from where the streaming should start */
|
||||
export type AuthUserProvidersStreamCursorValueInput = {
|
||||
id?: InputMaybe<Scalars['uuid']>;
|
||||
providerId?: InputMaybe<Scalars['String']>;
|
||||
};
|
||||
|
||||
/** User webauthn security keys. Don't modify its structure as Hasura Auth relies on it to function properly. */
|
||||
export type AuthUserSecurityKeys = {
|
||||
__typename?: 'authUserSecurityKeys';
|
||||
@@ -930,6 +997,10 @@ export type QueryRoot = {
|
||||
authRefreshToken?: Maybe<AuthRefreshTokens>;
|
||||
/** fetch data from the table: "auth.refresh_tokens" */
|
||||
authRefreshTokens: Array<AuthRefreshTokens>;
|
||||
/** fetch data from the table: "auth.user_providers" using primary key columns */
|
||||
authUserProvider?: Maybe<AuthUserProviders>;
|
||||
/** fetch data from the table: "auth.user_providers" */
|
||||
authUserProviders: Array<AuthUserProviders>;
|
||||
/** fetch data from the table: "auth.user_security_keys" using primary key columns */
|
||||
authUserSecurityKey?: Maybe<AuthUserSecurityKeys>;
|
||||
/** fetch data from the table: "auth.user_security_keys" */
|
||||
@@ -971,6 +1042,20 @@ export type QueryRootAuthRefreshTokensArgs = {
|
||||
};
|
||||
|
||||
|
||||
export type QueryRootAuthUserProviderArgs = {
|
||||
id: Scalars['uuid'];
|
||||
};
|
||||
|
||||
|
||||
export type QueryRootAuthUserProvidersArgs = {
|
||||
distinct_on?: InputMaybe<Array<AuthUserProvidersSelectColumn>>;
|
||||
limit?: InputMaybe<Scalars['Int']>;
|
||||
offset?: InputMaybe<Scalars['Int']>;
|
||||
order_by?: InputMaybe<Array<AuthUserProvidersOrderBy>>;
|
||||
where?: InputMaybe<AuthUserProvidersBoolExp>;
|
||||
};
|
||||
|
||||
|
||||
export type QueryRootAuthUserSecurityKeyArgs = {
|
||||
id: Scalars['uuid'];
|
||||
};
|
||||
@@ -1066,6 +1151,12 @@ export type SubscriptionRoot = {
|
||||
authRefreshTokens: Array<AuthRefreshTokens>;
|
||||
/** fetch data from the table in a streaming manner: "auth.refresh_tokens" */
|
||||
authRefreshTokens_stream: Array<AuthRefreshTokens>;
|
||||
/** fetch data from the table: "auth.user_providers" using primary key columns */
|
||||
authUserProvider?: Maybe<AuthUserProviders>;
|
||||
/** fetch data from the table: "auth.user_providers" */
|
||||
authUserProviders: Array<AuthUserProviders>;
|
||||
/** fetch data from the table in a streaming manner: "auth.user_providers" */
|
||||
authUserProviders_stream: Array<AuthUserProviders>;
|
||||
/** fetch data from the table: "auth.user_security_keys" using primary key columns */
|
||||
authUserSecurityKey?: Maybe<AuthUserSecurityKeys>;
|
||||
/** fetch data from the table: "auth.user_security_keys" */
|
||||
@@ -1124,6 +1215,27 @@ export type SubscriptionRootAuthRefreshTokensStreamArgs = {
|
||||
};
|
||||
|
||||
|
||||
export type SubscriptionRootAuthUserProviderArgs = {
|
||||
id: Scalars['uuid'];
|
||||
};
|
||||
|
||||
|
||||
export type SubscriptionRootAuthUserProvidersArgs = {
|
||||
distinct_on?: InputMaybe<Array<AuthUserProvidersSelectColumn>>;
|
||||
limit?: InputMaybe<Scalars['Int']>;
|
||||
offset?: InputMaybe<Scalars['Int']>;
|
||||
order_by?: InputMaybe<Array<AuthUserProvidersOrderBy>>;
|
||||
where?: InputMaybe<AuthUserProvidersBoolExp>;
|
||||
};
|
||||
|
||||
|
||||
export type SubscriptionRootAuthUserProvidersStreamArgs = {
|
||||
batch_size: Scalars['Int'];
|
||||
cursor: Array<InputMaybe<AuthUserProvidersStreamCursorInput>>;
|
||||
where?: InputMaybe<AuthUserProvidersBoolExp>;
|
||||
};
|
||||
|
||||
|
||||
export type SubscriptionRootAuthUserSecurityKeyArgs = {
|
||||
id: Scalars['uuid'];
|
||||
};
|
||||
@@ -1444,6 +1556,8 @@ export type Users = {
|
||||
/** An array relationship */
|
||||
securityKeys: Array<AuthUserSecurityKeys>;
|
||||
updatedAt: Scalars['timestamptz'];
|
||||
/** An array relationship */
|
||||
userProviders: Array<AuthUserProviders>;
|
||||
};
|
||||
|
||||
|
||||
@@ -1472,6 +1586,16 @@ export type UsersSecurityKeysArgs = {
|
||||
where?: InputMaybe<AuthUserSecurityKeysBoolExp>;
|
||||
};
|
||||
|
||||
|
||||
/** User account information. Don't modify its structure as Hasura Auth relies on it to function properly. */
|
||||
export type UsersUserProvidersArgs = {
|
||||
distinct_on?: InputMaybe<Array<AuthUserProvidersSelectColumn>>;
|
||||
limit?: InputMaybe<Scalars['Int']>;
|
||||
offset?: InputMaybe<Scalars['Int']>;
|
||||
order_by?: InputMaybe<Array<AuthUserProvidersOrderBy>>;
|
||||
where?: InputMaybe<AuthUserProvidersBoolExp>;
|
||||
};
|
||||
|
||||
/** Boolean expression to filter rows from the table "auth.users". All fields are combined with a logical 'AND'. */
|
||||
export type UsersBoolExp = {
|
||||
_and?: InputMaybe<Array<UsersBoolExp>>;
|
||||
@@ -1498,6 +1622,7 @@ export type UsersBoolExp = {
|
||||
refreshTokens?: InputMaybe<AuthRefreshTokensBoolExp>;
|
||||
securityKeys?: InputMaybe<AuthUserSecurityKeysBoolExp>;
|
||||
updatedAt?: InputMaybe<TimestamptzComparisonExp>;
|
||||
userProviders?: InputMaybe<AuthUserProvidersBoolExp>;
|
||||
};
|
||||
|
||||
/** Ordering options when selecting data from "auth.users". */
|
||||
@@ -1523,6 +1648,7 @@ export type UsersOrderBy = {
|
||||
refreshTokens_aggregate?: InputMaybe<AuthRefreshTokensAggregateOrderBy>;
|
||||
securityKeys_aggregate?: InputMaybe<AuthUserSecurityKeysAggregateOrderBy>;
|
||||
updatedAt?: InputMaybe<OrderBy>;
|
||||
userProviders_aggregate?: InputMaybe<AuthUserProvidersAggregateOrderBy>;
|
||||
};
|
||||
|
||||
/** select columns of table "auth.users" */
|
||||
|
||||
70
examples/react-apollo/src/profile/connect-socials.tsx
Normal file
70
examples/react-apollo/src/profile/connect-socials.tsx
Normal file
@@ -0,0 +1,70 @@
|
||||
import { gql } from '@apollo/client'
|
||||
import { Card, Group, Title } from '@mantine/core'
|
||||
import { useProviderLink } from '@nhost/react'
|
||||
import { useAuthQuery } from '@nhost/react-apollo'
|
||||
import { useEffect } from 'react'
|
||||
import { FaGithub } from 'react-icons/fa'
|
||||
import { useSearchParams } from 'react-router-dom'
|
||||
import AuthLink from 'src/components/AuthLink'
|
||||
import { AuthUserProviders } from 'src/generated'
|
||||
import { showNotification } from '@mantine/notifications'
|
||||
|
||||
export const ConnectSocials: React.FC = () => {
|
||||
let [searchParams, setSearchParams] = useSearchParams()
|
||||
|
||||
useEffect(() => {
|
||||
const error = searchParams.get('error')
|
||||
const errorDescription = searchParams.get('errorDescription')
|
||||
|
||||
if (error === 'bad-request' && errorDescription === 'social user already exists') {
|
||||
showNotification({
|
||||
color: 'red',
|
||||
title: 'Bad request',
|
||||
message: 'Social user already exists'
|
||||
})
|
||||
|
||||
searchParams.delete('error')
|
||||
searchParams.delete('errorDescription')
|
||||
|
||||
setSearchParams(searchParams)
|
||||
}
|
||||
}, [searchParams, setSearchParams])
|
||||
|
||||
const { github } = useProviderLink({
|
||||
connect: true,
|
||||
redirectTo: `${window.location.origin}/profile`
|
||||
})
|
||||
|
||||
const AUTH_USER_PROVIDERS = gql`
|
||||
query getAuthUserProviders {
|
||||
authUserProviders {
|
||||
id
|
||||
providerId
|
||||
}
|
||||
}
|
||||
`
|
||||
|
||||
const { data } = useAuthQuery<{
|
||||
authUserProviders: AuthUserProviders[]
|
||||
}>(AUTH_USER_PROVIDERS, {
|
||||
pollInterval: 5000,
|
||||
fetchPolicy: 'cache-and-network'
|
||||
})
|
||||
|
||||
const isGithubConnected = data?.authUserProviders?.some((item) => item.providerId === 'github')
|
||||
|
||||
return (
|
||||
<Card shadow="sm" p="lg" m="sm">
|
||||
<Title style={{ marginBottom: '1rem' }}>Connect with social providers</Title>
|
||||
{!isGithubConnected ? (
|
||||
<AuthLink leftIcon={<FaGithub />} link={github} color="#333" disabled={isGithubConnected}>
|
||||
Connect with GitHub
|
||||
</AuthLink>
|
||||
) : (
|
||||
<Group>
|
||||
<FaGithub /> <span>Github connected</span>
|
||||
</Group>
|
||||
)}
|
||||
</Card>
|
||||
)
|
||||
}
|
||||
@@ -4,6 +4,7 @@ import { useHasuraClaims, useNhostClient, useUserData } from '@nhost/react'
|
||||
|
||||
import { ChangeEmail } from './change-email'
|
||||
import { ChangePassword } from './change-password'
|
||||
import { ConnectSocials } from './connect-socials'
|
||||
import { Mfa } from './mfa'
|
||||
import { SecurityKeys } from './security-keys'
|
||||
|
||||
@@ -14,6 +15,7 @@ export const ProfilePage: React.FC = () => {
|
||||
return (
|
||||
<Container>
|
||||
<Title>Profile page</Title>
|
||||
<ConnectSocials />
|
||||
<SecurityKeys />
|
||||
<Mfa />
|
||||
<ChangeEmail />
|
||||
|
||||
@@ -1,5 +1,29 @@
|
||||
# @nhost-examples/react-gqty
|
||||
|
||||
## 1.2.0
|
||||
|
||||
### Minor Changes
|
||||
|
||||
- 768ca17: chore: update dependencies
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [768ca17]
|
||||
- @nhost/react@3.4.0
|
||||
|
||||
## 1.1.2
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [311374e]
|
||||
- @nhost/react@3.3.2
|
||||
|
||||
## 1.1.1
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- @nhost/react@3.3.1
|
||||
|
||||
## 1.1.0
|
||||
|
||||
### Minor Changes
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
{
|
||||
"name": "@nhost-examples/react-gqty",
|
||||
"private": true,
|
||||
"version": "1.1.0",
|
||||
"version": "1.2.0",
|
||||
"type": "module",
|
||||
"scripts": {
|
||||
"dev": "vite",
|
||||
@@ -20,13 +20,13 @@
|
||||
"devDependencies": {
|
||||
"@gqty/cli": "3.3.0-alpha-d8cdbf6.0",
|
||||
"@tailwindcss/forms": "^0.5.7",
|
||||
"@types/react": "^18.2.61",
|
||||
"@types/react-dom": "^18.2.19",
|
||||
"@types/react": "^18.2.73",
|
||||
"@types/react-dom": "^18.2.23",
|
||||
"@vitejs/plugin-react": "^3.1.0",
|
||||
"autoprefixer": "^10.4.17",
|
||||
"postcss": "^8.4.35",
|
||||
"tailwindcss": "^3.4.1",
|
||||
"autoprefixer": "^10.4.19",
|
||||
"postcss": "^8.4.38",
|
||||
"tailwindcss": "^3.4.3",
|
||||
"typescript": "^4.9.5",
|
||||
"vite": "^5.1.4"
|
||||
"vite": "^5.2.7"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,5 +1,23 @@
|
||||
# @nhost-examples/serverless-functions
|
||||
|
||||
## 0.2.0
|
||||
|
||||
### Minor Changes
|
||||
|
||||
- 768ca17: chore: update dependencies
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [768ca17]
|
||||
- @nhost/stripe-graphql-js@1.2.0
|
||||
|
||||
## 0.1.1
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [7789469]
|
||||
- @nhost/stripe-graphql-js@1.1.1
|
||||
|
||||
## 0.1.0
|
||||
|
||||
### Minor Changes
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
{
|
||||
"name": "@nhost-examples/serverless-functions",
|
||||
"private": true,
|
||||
"version": "0.1.0",
|
||||
"version": "0.2.0",
|
||||
"devDependencies": {
|
||||
"@types/express": "^4.17.21"
|
||||
},
|
||||
@@ -11,7 +11,7 @@
|
||||
"@pothos/core": "^3.41.0",
|
||||
"cross-fetch": "^3.1.8",
|
||||
"graphql": "16.8.1",
|
||||
"nodemailer": "^6.9.11",
|
||||
"nodemailer": "^6.9.13",
|
||||
"slugify": "^1.6.6",
|
||||
"stripe": "^11.18.0"
|
||||
}
|
||||
|
||||
@@ -1,5 +1,50 @@
|
||||
# @nhost-examples/vue-apollo
|
||||
|
||||
## 0.6.0
|
||||
|
||||
### Minor Changes
|
||||
|
||||
- 768ca17: chore: update dependencies
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [768ca17]
|
||||
- @nhost/apollo@6.2.0
|
||||
- @nhost/vue@2.5.0
|
||||
- @nhost/nhost-js@3.0.10
|
||||
|
||||
## 0.5.0
|
||||
|
||||
### Minor Changes
|
||||
|
||||
- 311374e: feat: add example of how to connect a social auth provider to an existing account
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [311374e]
|
||||
- @nhost/vue@2.4.0
|
||||
- @nhost/nhost-js@3.0.10
|
||||
- @nhost/apollo@6.1.2
|
||||
|
||||
## 0.4.1
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- 7789469: chore: address linter errors and remove unnecessary imports
|
||||
- @nhost/nhost-js@3.0.9
|
||||
- @nhost/apollo@6.1.1
|
||||
- @nhost/vue@2.3.1
|
||||
|
||||
## 0.4.0
|
||||
|
||||
### Minor Changes
|
||||
|
||||
- 08a7dd9: feat: add example workaround to the reset password ticket expired issue
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- f0a994a: fix: update allowedUrls and redirectTo to point to the profile page
|
||||
|
||||
## 0.3.1
|
||||
|
||||
### Patch Changes
|
||||
|
||||
@@ -9,7 +9,7 @@
|
||||
<h2>Verify Email</h2>
|
||||
<p>Use this link to verify your email:</p>
|
||||
<p>
|
||||
<a href="${link}">
|
||||
<a href="${clientUrl}/verify?ticket=${ticket}&redirectTo=${redirectTo}&type=emailVerify">
|
||||
Verify Email
|
||||
</a>
|
||||
</p>
|
||||
|
||||
@@ -9,7 +9,7 @@
|
||||
<h2>Reset Password</h2>
|
||||
<p>Use this link to reset your password:</p>
|
||||
<p>
|
||||
<a href="${link}">
|
||||
<a href="${clientUrl}/verify?ticket=${ticket}&redirectTo=${redirectTo}&type=emailVerify">
|
||||
Reset password
|
||||
</a>
|
||||
</p>
|
||||
|
||||
@@ -46,3 +46,15 @@ object_relationships:
|
||||
- name: user
|
||||
using:
|
||||
foreign_key_constraint_on: user_id
|
||||
select_permissions:
|
||||
- role: user
|
||||
permission:
|
||||
columns:
|
||||
- access_token
|
||||
- id
|
||||
- provider_id
|
||||
- refresh_token
|
||||
filter:
|
||||
user_id:
|
||||
_eq: X-Hasura-User-Id
|
||||
comment: ""
|
||||
|
||||
@@ -16,6 +16,7 @@ enableAllowList = false
|
||||
enableConsole = true
|
||||
enableRemoteSchemaPermissions = false
|
||||
enabledAPIs = ['metadata', 'graphql', 'pgdump', 'config']
|
||||
liveQueriesMultiplexedRefetchInterval = 1000
|
||||
|
||||
[hasura.logs]
|
||||
level = 'warn'
|
||||
@@ -28,17 +29,18 @@ httpPoolSize = 100
|
||||
version = 18
|
||||
|
||||
[auth]
|
||||
version = '0.27.0-beta1'
|
||||
version = '0.27.0-beta13'
|
||||
|
||||
[auth.elevatedPrivileges]
|
||||
mode = 'required'
|
||||
|
||||
[auth.redirections]
|
||||
clientUrl = 'https://vue-apollo.example.nhost.io'
|
||||
allowedUrls = ['https://vue-apollo.example.nhost.io/profile', 'https://react-apollo.example.nhost.io/profile', 'https://*.vercel.app','http://localhost:5173']
|
||||
allowedUrls = ['https://react-apollo.example.nhost.io', 'https://react-apollo.example.nhost.io/profile', 'https://vue-apollo.example.nhost.io', 'https://vue-apollo.example.nhost.io/profile', 'https://*.vercel.app', 'http://localhost:3000', 'http://localhost:3000/profile', 'http://localhost:5173', 'http://localhost:5173/profile']
|
||||
|
||||
[auth.signUp]
|
||||
enabled = true
|
||||
disableNewUsers = false
|
||||
|
||||
[auth.user]
|
||||
[auth.user.roles]
|
||||
@@ -67,7 +69,7 @@ expiresIn = 43200
|
||||
|
||||
[auth.method]
|
||||
[auth.method.anonymous]
|
||||
enabled = false
|
||||
enabled = true
|
||||
|
||||
[auth.method.emailPasswordless]
|
||||
enabled = true
|
||||
@@ -75,7 +77,7 @@ enabled = true
|
||||
[auth.method.emailPassword]
|
||||
hibpEnabled = false
|
||||
emailVerificationRequired = true
|
||||
passwordMinLength = 9
|
||||
passwordMinLength = 8
|
||||
|
||||
[auth.method.smsPasswordless]
|
||||
enabled = false
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
{
|
||||
"name": "@nhost-examples/vue-apollo",
|
||||
"private": true,
|
||||
"version": "0.3.1",
|
||||
"version": "0.6.0",
|
||||
"scripts": {
|
||||
"dev": "vite",
|
||||
"build": "vite build",
|
||||
@@ -14,7 +14,7 @@
|
||||
"verify:fix": "run-p prettier:fix lint:fix"
|
||||
},
|
||||
"dependencies": {
|
||||
"@apollo/client": "^3.9.5",
|
||||
"@apollo/client": "^3.9.9",
|
||||
"@mdi/font": "5.9.55",
|
||||
"@nhost/apollo": "workspace:^",
|
||||
"@nhost/nhost-js": "workspace:^",
|
||||
@@ -37,7 +37,7 @@
|
||||
"@xstate/inspect": "^0.6.5",
|
||||
"sass": "1.32.0",
|
||||
"typescript": "4.9.4",
|
||||
"vite": "^5.1.4",
|
||||
"vite": "^5.2.7",
|
||||
"vue-tsc": "^0.38.9"
|
||||
},
|
||||
"eslintConfig": {
|
||||
|
||||
@@ -15,5 +15,5 @@
|
||||
<script lang="ts" setup>
|
||||
import { useProviderLink } from '@nhost/vue'
|
||||
|
||||
const { github } = useProviderLink({ redirectTo: window.location.origin })
|
||||
const { github } = useProviderLink({ redirectTo: `${window.location.origin}/profile` })
|
||||
</script>
|
||||
|
||||
@@ -1,10 +1,32 @@
|
||||
<template>
|
||||
<div className="d-flex align-center flex-column">
|
||||
<v-card width="400">
|
||||
<v-card width="400" class="mb-2">
|
||||
<v-card-title>Profile page</v-card-title>
|
||||
<v-card-text> {{ userEmail }} </v-card-text>
|
||||
</v-card>
|
||||
|
||||
<v-card width="400">
|
||||
<v-card-text>
|
||||
<v-btn
|
||||
class="my-1"
|
||||
block
|
||||
variant="text"
|
||||
prepend-icon="mdi-github"
|
||||
color="white"
|
||||
style="background-color: #333"
|
||||
:href="github"
|
||||
v-if="!isGithubConnected"
|
||||
>
|
||||
Connect with GitHub
|
||||
</v-btn>
|
||||
|
||||
<span v-if="isGithubConnected">
|
||||
<v-icon>mdi-github</v-icon>
|
||||
Github connected {{ isGithubConnected }}
|
||||
</span>
|
||||
</v-card-text>
|
||||
</v-card>
|
||||
|
||||
<v-card width="400" class="mt-2 pa-4">
|
||||
<v-card-title>Add Security Key</v-card-title>
|
||||
|
||||
@@ -83,6 +105,17 @@
|
||||
>
|
||||
|
||||
<error-snack-bar v-model="showRemoveKeyError"></error-snack-bar>
|
||||
|
||||
<error-snack-bar v-model="showConnectProviderError" title="Bad request"
|
||||
><span class="text-white"></span
|
||||
></error-snack-bar>
|
||||
|
||||
<v-snackbar v-model="showConnectProviderError" vertical>
|
||||
<div class="pb-2 text-subtitle-1">Bad request</div>
|
||||
|
||||
<p>Social user already exists</p>
|
||||
</v-snackbar>
|
||||
|
||||
<v-snackbar v-model="showRemoveKeyError">
|
||||
Could not remove key
|
||||
<template #actions>
|
||||
@@ -95,22 +128,38 @@
|
||||
|
||||
<script lang="ts" setup>
|
||||
import { gql } from '@apollo/client/core'
|
||||
|
||||
import {
|
||||
useChangeEmail,
|
||||
useChangePassword,
|
||||
useElevateSecurityKeyEmail,
|
||||
useAddSecurityKey,
|
||||
useUserEmail,
|
||||
useUserId
|
||||
useUserId,
|
||||
useProviderLink
|
||||
} from '@nhost/vue'
|
||||
|
||||
import { useMutation, useQuery } from '@vue/apollo-composable'
|
||||
import { computed } from 'vue'
|
||||
import { ref, unref } from 'vue'
|
||||
import { ref, unref, computed, onMounted } from 'vue'
|
||||
import { useRoute, useRouter } from 'vue-router'
|
||||
|
||||
const email = ref('')
|
||||
const password = ref('')
|
||||
const nickname = ref('')
|
||||
const successSnackBar = ref(false)
|
||||
const showConnectProviderError = ref(false)
|
||||
|
||||
const router = useRouter()
|
||||
const route = useRoute()
|
||||
|
||||
onMounted(() => {
|
||||
const errorDescription = route.query.errorDescription
|
||||
|
||||
if (errorDescription === 'social user already exists') {
|
||||
showConnectProviderError.value = true
|
||||
router.replace({ query: undefined })
|
||||
}
|
||||
})
|
||||
|
||||
const userId = useUserId()
|
||||
const userEmail = useUserEmail()
|
||||
@@ -124,6 +173,19 @@ const { changeEmail, isLoading: isChangeEmailLoading } = useChangeEmail()
|
||||
const { changePassword, isLoading: isChangePasswordLoading } = useChangePassword()
|
||||
const { elevated, elevateEmailSecurityKey } = useElevateSecurityKeyEmail()
|
||||
const { add } = useAddSecurityKey()
|
||||
const { github } = useProviderLink({
|
||||
connect: true,
|
||||
redirectTo: `${window.location.origin}/profile`
|
||||
})
|
||||
|
||||
const AUTH_USER_PROVIDERS = gql`
|
||||
query getAuthUserProviders {
|
||||
authUserProviders {
|
||||
id
|
||||
providerId
|
||||
}
|
||||
}
|
||||
`
|
||||
|
||||
const SECURITY_KEYS_LIST = gql`
|
||||
query securityKeys($userId: uuid!) {
|
||||
@@ -142,6 +204,14 @@ const REMOVE_SECURITY_KEY = gql`
|
||||
}
|
||||
`
|
||||
|
||||
const { result: authUserProvidersQueryResult } = useQuery(AUTH_USER_PROVIDERS)
|
||||
|
||||
const isGithubConnected = computed(() =>
|
||||
authUserProvidersQueryResult.value?.authUserProviders.some(
|
||||
(item: any) => item.providerId === 'github'
|
||||
)
|
||||
)
|
||||
|
||||
const { result: securityKeys, refetch } = useQuery(SECURITY_KEYS_LIST, { userId }, {})
|
||||
const { mutate: removeKey } = useMutation(REMOVE_SECURITY_KEY)
|
||||
|
||||
|
||||
30
examples/vue-apollo/src/pages/VerifyEmail.vue
Normal file
30
examples/vue-apollo/src/pages/VerifyEmail.vue
Normal file
@@ -0,0 +1,30 @@
|
||||
<template>
|
||||
<div className="d-flex align-center flex-column">
|
||||
<v-card width="400" v-if="!loading">
|
||||
<v-card-text>Failed to authenticate with magick link</v-card-text>
|
||||
</v-card>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
import { ref, onMounted } from 'vue'
|
||||
import { useRoute } from 'vue-router'
|
||||
import { useNhostClient } from '@nhost/vue'
|
||||
|
||||
const { nhost } = useNhostClient()
|
||||
const route = useRoute()
|
||||
|
||||
const loading = ref(true)
|
||||
|
||||
onMounted(() => {
|
||||
const ticket = route.query.ticket
|
||||
const redirectTo = route.query.redirectTo
|
||||
const type = route.query.type
|
||||
|
||||
if (ticket && redirectTo && type) {
|
||||
window.location.href = `${nhost.auth.url}/verify?ticket=${ticket}&type=${type}&redirectTo=${redirectTo}`
|
||||
}
|
||||
|
||||
loading.value = false
|
||||
})
|
||||
</script>
|
||||
@@ -2,8 +2,20 @@
|
||||
<form @submit="handleSignIn">
|
||||
<v-text-field v-model="email" label="Email" />
|
||||
<v-text-field v-model="password" label="Password" type="password" />
|
||||
<v-btn block color="primary" class="my-1" type="submit" :disabled="isLoading" :loading="isLoading"> Sign in </v-btn>
|
||||
<v-btn
|
||||
block
|
||||
color="primary"
|
||||
class="my-1"
|
||||
type="submit"
|
||||
:disabled="isLoading"
|
||||
:loading="isLoading"
|
||||
>
|
||||
Sign in
|
||||
</v-btn>
|
||||
</form>
|
||||
<v-btn class="my-1" block variant="text" color="primary" to="/signin/forgot-password">
|
||||
Forgot password?
|
||||
</v-btn>
|
||||
<v-btn class="my-1" block variant="text" color="primary" to="/signin">
|
||||
← Other Sign-in Options
|
||||
</v-btn>
|
||||
|
||||
38
examples/vue-apollo/src/pages/sign-in/ForgotPassword.vue
Normal file
38
examples/vue-apollo/src/pages/sign-in/ForgotPassword.vue
Normal file
@@ -0,0 +1,38 @@
|
||||
<template>
|
||||
<form @submit="handleSendResetPasswordEmail">
|
||||
<v-text-field v-model="email" label="Email" />
|
||||
<v-btn block color="primary" class="my-1" type="submit"> Reset password </v-btn>
|
||||
|
||||
<v-dialog v-model="emailSent">
|
||||
<v-card>
|
||||
<v-card-title>
|
||||
<span class="text-h5">Verification email sent</span>
|
||||
</v-card-title>
|
||||
<v-card-text>
|
||||
A email has been sent to {{ email }}. Please follow the link to reset the password.
|
||||
</v-card-text>
|
||||
<v-card-actions class="justify-center d-flex">
|
||||
<v-btn text @click="emailSent = false"> Close </v-btn>
|
||||
</v-card-actions>
|
||||
</v-card>
|
||||
</v-dialog>
|
||||
</form>
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
import { ref } from 'vue'
|
||||
import { useResetPassword } from '@nhost/vue'
|
||||
|
||||
const email = ref('')
|
||||
const emailSent = ref(false)
|
||||
|
||||
const { resetPassword } = useResetPassword({
|
||||
redirectTo: '/profile'
|
||||
})
|
||||
|
||||
const handleSendResetPasswordEmail = async (e: Event) => {
|
||||
e.preventDefault()
|
||||
await resetPassword(email)
|
||||
emailSent.value = true
|
||||
}
|
||||
</script>
|
||||
@@ -14,12 +14,15 @@ import SignUpEmailPasword from './pages/sign-up/EmailPassword.vue'
|
||||
import SignUpEmailPaswordless from './pages/sign-up/EmailPasswordless.vue'
|
||||
import SignUpEmailSecurityKey from './pages/sign-up/SecurityKey.vue'
|
||||
import SignInEmailSecurityKey from './pages/sign-in/SecurityKey.vue'
|
||||
import ForgotPassword from './pages/sign-in/ForgotPassword.vue'
|
||||
import SignUp from './pages/sign-up/IndexPage.vue'
|
||||
import Signout from './pages/SignoutPage.vue'
|
||||
import StoragePage from './pages/StoragePage.vue'
|
||||
import VerifyPage from './pages/VerifyEmail.vue'
|
||||
|
||||
export const routes: RouteRecordRaw[] = [
|
||||
{ path: '/', component: Index, meta: { auth: true } },
|
||||
{ path: '/verify', component: VerifyPage },
|
||||
{ path: '/profile', component: Profile, meta: { auth: true } },
|
||||
{ path: '/about', component: AboutPage },
|
||||
{ path: '/signout', component: Signout },
|
||||
@@ -39,6 +42,10 @@ export const routes: RouteRecordRaw[] = [
|
||||
{
|
||||
path: 'security-key',
|
||||
component: SignInEmailSecurityKey
|
||||
},
|
||||
{
|
||||
path: 'forgot-password',
|
||||
component: ForgotPassword
|
||||
}
|
||||
]
|
||||
},
|
||||
|
||||
@@ -1,5 +1,32 @@
|
||||
# @nhost-examples/vue-quickstart
|
||||
|
||||
## 0.2.0
|
||||
|
||||
### Minor Changes
|
||||
|
||||
- 768ca17: chore: update dependencies
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [768ca17]
|
||||
- @nhost/apollo@6.2.0
|
||||
- @nhost/vue@2.5.0
|
||||
|
||||
## 0.1.2
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [311374e]
|
||||
- @nhost/vue@2.4.0
|
||||
- @nhost/apollo@6.1.2
|
||||
|
||||
## 0.1.1
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- @nhost/apollo@6.1.1
|
||||
- @nhost/vue@2.3.1
|
||||
|
||||
## 0.1.0
|
||||
|
||||
### Minor Changes
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@nhost-examples/vue-quickstart",
|
||||
"version": "0.1.0",
|
||||
"version": "0.2.0",
|
||||
"private": true,
|
||||
"scripts": {
|
||||
"build": "vite build",
|
||||
@@ -11,7 +11,7 @@
|
||||
"test": "vitest"
|
||||
},
|
||||
"dependencies": {
|
||||
"@apollo/client": "^3.9.5",
|
||||
"@apollo/client": "^3.9.9",
|
||||
"@nhost/apollo": "workspace:^",
|
||||
"@nhost/vue": "workspace:^",
|
||||
"@vue/apollo-composable": "4.0.0-alpha.18",
|
||||
@@ -23,11 +23,11 @@
|
||||
},
|
||||
"devDependencies": {
|
||||
"@antfu/eslint-config": "^0.23.1",
|
||||
"@iconify-json/carbon": "^1.1.30",
|
||||
"@types/node": "^16.18.86",
|
||||
"@iconify-json/carbon": "^1.1.31",
|
||||
"@types/node": "^16.18.93",
|
||||
"@unocss/reset": "^0.33.5",
|
||||
"@vitejs/plugin-vue": "^4.6.2",
|
||||
"@vue/test-utils": "^2.4.4",
|
||||
"@vue/test-utils": "^2.4.5",
|
||||
"eslint": "^8.57.0",
|
||||
"jsdom": "^19.0.0",
|
||||
"pnpm": "^7.33.7",
|
||||
@@ -35,7 +35,7 @@
|
||||
"unocss": "^0.33.5",
|
||||
"unplugin-auto-import": "^0.17.5",
|
||||
"unplugin-vue-components": "^0.26.0",
|
||||
"vite": "^5.1.4",
|
||||
"vite": "^5.2.7",
|
||||
"vite-plugin-pages": "^0.28.0",
|
||||
"vue-tsc": "^0.38.9"
|
||||
}
|
||||
|
||||
6
flake.lock
generated
6
flake.lock
generated
@@ -40,11 +40,11 @@
|
||||
"nixpkgs": "nixpkgs"
|
||||
},
|
||||
"locked": {
|
||||
"lastModified": 1709101436,
|
||||
"narHash": "sha256-77w34voAwaCYDnXTpe6cXDDFEMOcXbAhXWsO38YUHmE=",
|
||||
"lastModified": 1709722688,
|
||||
"narHash": "sha256-ng5a9klcxohFhs9xfNAcZWTveM4SlMWoRoWDYyXoECE=",
|
||||
"owner": "nhost",
|
||||
"repo": "nixops",
|
||||
"rev": "9ae747fefe6bb611d115de2f5d2a04a22dc324b2",
|
||||
"rev": "919e405ab485c099a42d44a2936cab2d3b1bd444",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
|
||||
@@ -1,5 +1,27 @@
|
||||
# @nhost/apollo
|
||||
|
||||
## 6.2.0
|
||||
|
||||
### Minor Changes
|
||||
|
||||
- 768ca17: chore: update dependencies
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- @nhost/nhost-js@3.0.10
|
||||
|
||||
## 6.1.2
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- @nhost/nhost-js@3.0.10
|
||||
|
||||
## 6.1.1
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- @nhost/nhost-js@3.0.9
|
||||
|
||||
## 6.1.0
|
||||
|
||||
### Minor Changes
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@nhost/apollo",
|
||||
"version": "6.1.0",
|
||||
"version": "6.2.0",
|
||||
"description": "Nhost Apollo Client library",
|
||||
"license": "MIT",
|
||||
"keywords": [
|
||||
@@ -65,11 +65,11 @@
|
||||
},
|
||||
"dependencies": {
|
||||
"graphql": "16.8.1",
|
||||
"graphql-ws": "^5.15.0",
|
||||
"graphql-ws": "^5.16.0",
|
||||
"jwt-decode": "^3.1.2"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@apollo/client": "^3.9.5",
|
||||
"@apollo/client": "^3.9.9",
|
||||
"@nhost/nhost-js": "workspace:*"
|
||||
}
|
||||
}
|
||||
@@ -1,5 +1,11 @@
|
||||
# @nhost/google-translation
|
||||
|
||||
## 0.2.0
|
||||
|
||||
### Minor Changes
|
||||
|
||||
- 768ca17: chore: update dependencies
|
||||
|
||||
## 0.1.0
|
||||
|
||||
### Minor Changes
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@nhost/google-translation",
|
||||
"version": "0.1.0",
|
||||
"version": "0.2.0",
|
||||
"description": "Google Translation GraphQL API",
|
||||
"license": "MIT",
|
||||
"keywords": [
|
||||
@@ -48,7 +48,7 @@
|
||||
"graphql-request": "^6.1.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@types/node": "^16.18.86",
|
||||
"@types/node": "^16.18.93",
|
||||
"dotenv": "^16.4.5",
|
||||
"typescript": "^4.9.5"
|
||||
}
|
||||
|
||||
@@ -1,5 +1,32 @@
|
||||
# @nhost/react-apollo
|
||||
|
||||
## 11.0.0
|
||||
|
||||
### Minor Changes
|
||||
|
||||
- 768ca17: chore: update dependencies
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [768ca17]
|
||||
- @nhost/apollo@6.2.0
|
||||
- @nhost/react@3.4.0
|
||||
|
||||
## 10.0.2
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [311374e]
|
||||
- @nhost/react@3.3.2
|
||||
- @nhost/apollo@6.1.2
|
||||
|
||||
## 10.0.1
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- @nhost/apollo@6.1.1
|
||||
- @nhost/react@3.3.1
|
||||
|
||||
## 10.0.0
|
||||
|
||||
### Minor Changes
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@nhost/react-apollo",
|
||||
"version": "10.0.0",
|
||||
"version": "11.0.0",
|
||||
"description": "Nhost React Apollo client",
|
||||
"license": "MIT",
|
||||
"keywords": [
|
||||
@@ -71,9 +71,9 @@
|
||||
"react-dom": "^17.0.0 || ^18.0.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@apollo/client": "^3.9.5",
|
||||
"@apollo/client": "^3.9.9",
|
||||
"@nhost/react": "workspace:*",
|
||||
"@types/react": "^18.2.61",
|
||||
"@types/react": "^18.2.73",
|
||||
"graphql": "16.8.1",
|
||||
"react": "^18.2.0",
|
||||
"react-dom": "^18.2.0"
|
||||
|
||||
@@ -1,5 +1,29 @@
|
||||
# @nhost/react-urql
|
||||
|
||||
## 8.0.0
|
||||
|
||||
### Minor Changes
|
||||
|
||||
- 768ca17: chore: update dependencies
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [768ca17]
|
||||
- @nhost/react@3.4.0
|
||||
|
||||
## 7.0.2
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [311374e]
|
||||
- @nhost/react@3.3.2
|
||||
|
||||
## 7.0.1
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- @nhost/react@3.3.1
|
||||
|
||||
## 7.0.0
|
||||
|
||||
### Minor Changes
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@nhost/react-urql",
|
||||
"version": "7.0.0",
|
||||
"version": "8.0.0",
|
||||
"description": "Nhost React URQL client",
|
||||
"license": "MIT",
|
||||
"keywords": [
|
||||
@@ -61,7 +61,7 @@
|
||||
"dependencies": {
|
||||
"@urql/devtools": "^2.0.3",
|
||||
"@urql/exchange-refocus": "^1.0.2",
|
||||
"graphql-ws": "^5.15.0"
|
||||
"graphql-ws": "^5.16.0"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"@nhost/react": "workspace:*",
|
||||
@@ -72,7 +72,7 @@
|
||||
},
|
||||
"devDependencies": {
|
||||
"@nhost/react": "workspace:*",
|
||||
"@types/react": "^18.2.61",
|
||||
"@types/react": "^18.2.73",
|
||||
"graphql": "16.8.1",
|
||||
"react": "^18.2.0",
|
||||
"react-dom": "^18.2.0",
|
||||
|
||||
@@ -1,5 +1,17 @@
|
||||
# @nhost/stripe-graphql-js
|
||||
|
||||
## 1.2.0
|
||||
|
||||
### Minor Changes
|
||||
|
||||
- 768ca17: chore: update dependencies
|
||||
|
||||
## 1.1.1
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- 7789469: chore: address linter errors and remove unnecessary imports
|
||||
|
||||
## 1.1.0
|
||||
|
||||
### Minor Changes
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@nhost/stripe-graphql-js",
|
||||
"version": "1.1.0",
|
||||
"version": "1.2.0",
|
||||
"description": "Stripe GraphQL API",
|
||||
"license": "MIT",
|
||||
"keywords": [
|
||||
@@ -42,14 +42,14 @@
|
||||
"dependencies": {
|
||||
"@pothos/core": "^3.41.0",
|
||||
"graphql": "16.8.1",
|
||||
"graphql-scalars": "^1.22.5",
|
||||
"graphql-scalars": "^1.23.0",
|
||||
"graphql-yoga": "^3.9.1",
|
||||
"jsonwebtoken": "^9.0.2",
|
||||
"stripe": "^11.18.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@types/jsonwebtoken": "^9.0.6",
|
||||
"@types/node": "^18.19.21",
|
||||
"@types/node": "^18.19.28",
|
||||
"dotenv": "^16.4.5",
|
||||
"ts-node-dev": "^2.0.0",
|
||||
"typescript": "^4.9.5"
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
import { createYoga, YogaInitialContext } from 'graphql-yoga'
|
||||
import { createServer } from 'node:http'
|
||||
|
||||
import { schema } from './schema'
|
||||
import { Context, CreateServerProps } from './types'
|
||||
@@ -9,7 +8,7 @@ const createStripeGraphQLServer = ({
|
||||
cors,
|
||||
isAllowed,
|
||||
graphiql,
|
||||
maskedErrors = true,
|
||||
maskedErrors = true
|
||||
}: CreateServerProps = {}) => {
|
||||
const context = (context: YogaInitialContext): Context => {
|
||||
const { request } = context
|
||||
@@ -53,7 +52,7 @@ const createStripeGraphQLServer = ({
|
||||
context,
|
||||
schema,
|
||||
graphqlEndpoint: '*',
|
||||
maskedErrors,
|
||||
maskedErrors
|
||||
})
|
||||
|
||||
return yoga
|
||||
|
||||
25
package.json
25
package.json
@@ -54,14 +54,14 @@
|
||||
"dashboard"
|
||||
],
|
||||
"devDependencies": {
|
||||
"@babel/core": "^7.24.0",
|
||||
"@babel/eslint-parser": "^7.23.10",
|
||||
"@babel/plugin-syntax-flow": "^7.23.3",
|
||||
"@babel/core": "^7.24.3",
|
||||
"@babel/eslint-parser": "^7.24.1",
|
||||
"@babel/plugin-syntax-flow": "^7.24.1",
|
||||
"@babel/plugin-transform-react-jsx": "^7.23.4",
|
||||
"@changesets/cli": "^2.27.1",
|
||||
"@faker-js/faker": "^7.6.0",
|
||||
"@rollup/plugin-replace": "^5.0.5",
|
||||
"@types/node": "^16.18.86",
|
||||
"@types/node": "^16.18.93",
|
||||
"@typescript-eslint/eslint-plugin": "^5.62.0",
|
||||
"@typescript-eslint/parser": "^5.62.0",
|
||||
"@vitejs/plugin-react": "^4.2.1",
|
||||
@@ -74,18 +74,18 @@
|
||||
"eslint-plugin-jsx-a11y": "^6.8.0",
|
||||
"eslint-plugin-node": "^11.1.0",
|
||||
"eslint-plugin-promise": "^6.1.1",
|
||||
"eslint-plugin-react": "^7.33.2",
|
||||
"eslint-plugin-react": "^7.34.1",
|
||||
"eslint-plugin-react-hooks": "^4.6.0",
|
||||
"eslint-plugin-vue": "^9.22.0",
|
||||
"eslint-plugin-vue": "^9.24.0",
|
||||
"husky": "^8.0.3",
|
||||
"npm-run-all": "^4.1.5",
|
||||
"prettier": "^2.8.8",
|
||||
"turbo": "1.11.3",
|
||||
"typedoc": "^0.22.18",
|
||||
"typescript": "4.9.5",
|
||||
"vite": "^5.1.4",
|
||||
"vite-plugin-dts": "^3.7.3",
|
||||
"vite-tsconfig-paths": "^4.3.1",
|
||||
"vite": "^5.2.7",
|
||||
"vite-plugin-dts": "^3.8.1",
|
||||
"vite-tsconfig-paths": "^4.3.2",
|
||||
"vitest": "^0.32.4"
|
||||
},
|
||||
"resolutions": {
|
||||
@@ -135,7 +135,12 @@
|
||||
"semver@<5.7.2": ">=5.7.2",
|
||||
"semver@>=6.0.0 <6.3.1": ">=6.3.1",
|
||||
"semver@>=7.0.0 <7.5.2": ">=7.5.2",
|
||||
"follow-redirects@<1.15.4": ">=1.15.4"
|
||||
"follow-redirects@>1.15.6": ">=1.15.6",
|
||||
"webpack-dev-middleware@<=5.3.3": ">=5.3.4",
|
||||
"katex@>=0.11.0 <0.16.10": ">=0.16.10",
|
||||
"katex@>=0.15.4 <0.16.10": ">=0.16.10",
|
||||
"katex@>=0.10.0-beta <0.16.10": ">=0.16.10",
|
||||
"express@<4.19.2": ">=4.19.2"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,5 +1,11 @@
|
||||
# @nhost/docgen
|
||||
|
||||
## 0.3.0
|
||||
|
||||
### Minor Changes
|
||||
|
||||
- 768ca17: chore: update dependencies
|
||||
|
||||
## 0.2.0
|
||||
|
||||
### Minor Changes
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
"name": "@nhost/docgen",
|
||||
"description": "Documentation generator for classes and functions",
|
||||
"private": true,
|
||||
"version": "0.2.0",
|
||||
"version": "0.3.0",
|
||||
"license": "MIT",
|
||||
"main": "dist/index.cjs.js",
|
||||
"types": "dist/index.d.ts",
|
||||
@@ -33,7 +33,7 @@
|
||||
"docgen": "dist/index.js"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@types/node": "^16.18.86",
|
||||
"@types/node": "^16.18.93",
|
||||
"@types/prettier": "^2.7.3",
|
||||
"rimraf": "^5.0.5",
|
||||
"typescript": "^4.9.5"
|
||||
@@ -43,6 +43,6 @@
|
||||
"commander": "^11.1.0",
|
||||
"just-kebab-case": "^4.2.0",
|
||||
"prettier": "^2.8.8",
|
||||
"valtio": "^1.13.1"
|
||||
"valtio": "^1.13.2"
|
||||
}
|
||||
}
|
||||
@@ -1,5 +1,11 @@
|
||||
# @nhost/graphql-js
|
||||
|
||||
## 0.1.9
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- 7789469: fix: resolve process is undefined error when running with vitejs
|
||||
|
||||
## 0.1.8
|
||||
|
||||
### Patch Changes
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@nhost/graphql-js",
|
||||
"version": "0.1.8",
|
||||
"version": "0.1.9",
|
||||
"description": "Nhost GraphQL client",
|
||||
"license": "MIT",
|
||||
"keywords": [
|
||||
@@ -55,7 +55,7 @@
|
||||
"dependencies": {
|
||||
"@graphql-typed-document-node/core": "^3.2.0",
|
||||
"isomorphic-unfetch": "^3.1.0",
|
||||
"jose": "^5.2.2"
|
||||
"jose": "^5.2.3"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"graphql": "^14.0.0 || ^15.0.0 || ^16.0.0"
|
||||
|
||||
@@ -104,7 +104,7 @@ export class NhostGraphqlClient {
|
||||
const { headers, ...otherOptions } = config || {}
|
||||
const { query, operationName } = resolveRequestDocument(requestOptions.document)
|
||||
|
||||
if (!process.env.TEST_MODE) {
|
||||
if (typeof process !== 'undefined' && !process.env.TEST_MODE) {
|
||||
// We skip this while running unit tests because the accessToken is generated using faker
|
||||
await this.awaitForValidAccessTokenOrNull()
|
||||
}
|
||||
|
||||
@@ -1,5 +1,15 @@
|
||||
# @nhost/hasura-auth-js
|
||||
|
||||
## 2.4.0
|
||||
|
||||
### Minor Changes
|
||||
|
||||
- 311374e: fix: ensure that the user remains signed in even after being redirected with an error following an attempt to connect with a social provider
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- 1623e9b: chore: update `@simplewebauthn/browser` to `9.0.1`
|
||||
|
||||
## 2.3.1
|
||||
|
||||
### Patch Changes
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user