Refactor client config (#529)
* Refactor client config * Fix server tests * Fix lint
This commit is contained in:
2
front/.gitignore
vendored
2
front/.gitignore
vendored
@ -23,3 +23,5 @@ build-storybook.log
|
|||||||
npm-debug.log*
|
npm-debug.log*
|
||||||
yarn-debug.log*
|
yarn-debug.log*
|
||||||
yarn-error.log*
|
yarn-error.log*
|
||||||
|
|
||||||
|
.nyc_output
|
||||||
|
|||||||
@ -29,6 +29,13 @@ export type Analytics = {
|
|||||||
success: Scalars['Boolean'];
|
success: Scalars['Boolean'];
|
||||||
};
|
};
|
||||||
|
|
||||||
|
export type AuthProviders = {
|
||||||
|
__typename?: 'AuthProviders';
|
||||||
|
google: Scalars['Boolean'];
|
||||||
|
magicLink: Scalars['Boolean'];
|
||||||
|
password: Scalars['Boolean'];
|
||||||
|
};
|
||||||
|
|
||||||
export type AuthToken = {
|
export type AuthToken = {
|
||||||
__typename?: 'AuthToken';
|
__typename?: 'AuthToken';
|
||||||
expiresAt: Scalars['DateTime'];
|
expiresAt: Scalars['DateTime'];
|
||||||
@ -57,8 +64,10 @@ export type BoolFilter = {
|
|||||||
|
|
||||||
export type ClientConfig = {
|
export type ClientConfig = {
|
||||||
__typename?: 'ClientConfig';
|
__typename?: 'ClientConfig';
|
||||||
display_google_login: Scalars['Boolean'];
|
authProviders: AuthProviders;
|
||||||
prefill_login_with_seed: Scalars['Boolean'];
|
debugMode: Scalars['Boolean'];
|
||||||
|
demoMode: Scalars['Boolean'];
|
||||||
|
telemetry: Telemetry;
|
||||||
};
|
};
|
||||||
|
|
||||||
export type Comment = {
|
export type Comment = {
|
||||||
@ -756,11 +765,11 @@ export type CompanyOrderByRelationAggregateInput = {
|
|||||||
|
|
||||||
export type CompanyOrderByWithRelationInput = {
|
export type CompanyOrderByWithRelationInput = {
|
||||||
accountOwner?: InputMaybe<UserOrderByWithRelationInput>;
|
accountOwner?: InputMaybe<UserOrderByWithRelationInput>;
|
||||||
accountOwnerId?: InputMaybe<SortOrderInput>;
|
accountOwnerId?: InputMaybe<SortOrder>;
|
||||||
address?: InputMaybe<SortOrder>;
|
address?: InputMaybe<SortOrder>;
|
||||||
createdAt?: InputMaybe<SortOrder>;
|
createdAt?: InputMaybe<SortOrder>;
|
||||||
domainName?: InputMaybe<SortOrder>;
|
domainName?: InputMaybe<SortOrder>;
|
||||||
employees?: InputMaybe<SortOrderInput>;
|
employees?: InputMaybe<SortOrder>;
|
||||||
id?: InputMaybe<SortOrder>;
|
id?: InputMaybe<SortOrder>;
|
||||||
name?: InputMaybe<SortOrder>;
|
name?: InputMaybe<SortOrder>;
|
||||||
people?: InputMaybe<PersonOrderByRelationAggregateInput>;
|
people?: InputMaybe<PersonOrderByRelationAggregateInput>;
|
||||||
@ -1247,11 +1256,6 @@ export type NullableStringFieldUpdateOperationsInput = {
|
|||||||
set?: InputMaybe<Scalars['String']>;
|
set?: InputMaybe<Scalars['String']>;
|
||||||
};
|
};
|
||||||
|
|
||||||
export enum NullsOrder {
|
|
||||||
First = 'first',
|
|
||||||
Last = 'last'
|
|
||||||
}
|
|
||||||
|
|
||||||
export type Person = {
|
export type Person = {
|
||||||
__typename?: 'Person';
|
__typename?: 'Person';
|
||||||
_commentCount: Scalars['Int'];
|
_commentCount: Scalars['Int'];
|
||||||
@ -1332,7 +1336,7 @@ export type PersonOrderByRelationAggregateInput = {
|
|||||||
export type PersonOrderByWithRelationInput = {
|
export type PersonOrderByWithRelationInput = {
|
||||||
city?: InputMaybe<SortOrder>;
|
city?: InputMaybe<SortOrder>;
|
||||||
company?: InputMaybe<CompanyOrderByWithRelationInput>;
|
company?: InputMaybe<CompanyOrderByWithRelationInput>;
|
||||||
companyId?: InputMaybe<SortOrderInput>;
|
companyId?: InputMaybe<SortOrder>;
|
||||||
createdAt?: InputMaybe<SortOrder>;
|
createdAt?: InputMaybe<SortOrder>;
|
||||||
email?: InputMaybe<SortOrder>;
|
email?: InputMaybe<SortOrder>;
|
||||||
firstName?: InputMaybe<SortOrder>;
|
firstName?: InputMaybe<SortOrder>;
|
||||||
@ -1567,6 +1571,7 @@ export type PipelineProgressCreateInput = {
|
|||||||
|
|
||||||
export type PipelineProgressCreateManyPipelineInput = {
|
export type PipelineProgressCreateManyPipelineInput = {
|
||||||
amount?: InputMaybe<Scalars['Int']>;
|
amount?: InputMaybe<Scalars['Int']>;
|
||||||
|
closeDate?: InputMaybe<Scalars['DateTime']>;
|
||||||
createdAt?: InputMaybe<Scalars['DateTime']>;
|
createdAt?: InputMaybe<Scalars['DateTime']>;
|
||||||
id?: InputMaybe<Scalars['String']>;
|
id?: InputMaybe<Scalars['String']>;
|
||||||
pipelineStageId: Scalars['String'];
|
pipelineStageId: Scalars['String'];
|
||||||
@ -1582,6 +1587,7 @@ export type PipelineProgressCreateManyPipelineInputEnvelope = {
|
|||||||
|
|
||||||
export type PipelineProgressCreateManyPipelineStageInput = {
|
export type PipelineProgressCreateManyPipelineStageInput = {
|
||||||
amount?: InputMaybe<Scalars['Int']>;
|
amount?: InputMaybe<Scalars['Int']>;
|
||||||
|
closeDate?: InputMaybe<Scalars['DateTime']>;
|
||||||
createdAt?: InputMaybe<Scalars['DateTime']>;
|
createdAt?: InputMaybe<Scalars['DateTime']>;
|
||||||
id?: InputMaybe<Scalars['String']>;
|
id?: InputMaybe<Scalars['String']>;
|
||||||
pipelineId: Scalars['String'];
|
pipelineId: Scalars['String'];
|
||||||
@ -1597,6 +1603,7 @@ export type PipelineProgressCreateManyPipelineStageInputEnvelope = {
|
|||||||
|
|
||||||
export type PipelineProgressCreateManyWorkspaceInput = {
|
export type PipelineProgressCreateManyWorkspaceInput = {
|
||||||
amount?: InputMaybe<Scalars['Int']>;
|
amount?: InputMaybe<Scalars['Int']>;
|
||||||
|
closeDate?: InputMaybe<Scalars['DateTime']>;
|
||||||
createdAt?: InputMaybe<Scalars['DateTime']>;
|
createdAt?: InputMaybe<Scalars['DateTime']>;
|
||||||
id?: InputMaybe<Scalars['String']>;
|
id?: InputMaybe<Scalars['String']>;
|
||||||
pipelineId: Scalars['String'];
|
pipelineId: Scalars['String'];
|
||||||
@ -1642,6 +1649,7 @@ export type PipelineProgressCreateOrConnectWithoutWorkspaceInput = {
|
|||||||
|
|
||||||
export type PipelineProgressCreateWithoutPipelineInput = {
|
export type PipelineProgressCreateWithoutPipelineInput = {
|
||||||
amount?: InputMaybe<Scalars['Int']>;
|
amount?: InputMaybe<Scalars['Int']>;
|
||||||
|
closeDate?: InputMaybe<Scalars['DateTime']>;
|
||||||
createdAt?: InputMaybe<Scalars['DateTime']>;
|
createdAt?: InputMaybe<Scalars['DateTime']>;
|
||||||
id?: InputMaybe<Scalars['String']>;
|
id?: InputMaybe<Scalars['String']>;
|
||||||
pipelineStage: PipelineStageCreateNestedOneWithoutPipelineProgressesInput;
|
pipelineStage: PipelineStageCreateNestedOneWithoutPipelineProgressesInput;
|
||||||
@ -1652,6 +1660,7 @@ export type PipelineProgressCreateWithoutPipelineInput = {
|
|||||||
|
|
||||||
export type PipelineProgressCreateWithoutPipelineStageInput = {
|
export type PipelineProgressCreateWithoutPipelineStageInput = {
|
||||||
amount?: InputMaybe<Scalars['Int']>;
|
amount?: InputMaybe<Scalars['Int']>;
|
||||||
|
closeDate?: InputMaybe<Scalars['DateTime']>;
|
||||||
createdAt?: InputMaybe<Scalars['DateTime']>;
|
createdAt?: InputMaybe<Scalars['DateTime']>;
|
||||||
id?: InputMaybe<Scalars['String']>;
|
id?: InputMaybe<Scalars['String']>;
|
||||||
pipeline: PipelineCreateNestedOneWithoutPipelineProgressesInput;
|
pipeline: PipelineCreateNestedOneWithoutPipelineProgressesInput;
|
||||||
@ -1662,6 +1671,7 @@ export type PipelineProgressCreateWithoutPipelineStageInput = {
|
|||||||
|
|
||||||
export type PipelineProgressCreateWithoutWorkspaceInput = {
|
export type PipelineProgressCreateWithoutWorkspaceInput = {
|
||||||
amount?: InputMaybe<Scalars['Int']>;
|
amount?: InputMaybe<Scalars['Int']>;
|
||||||
|
closeDate?: InputMaybe<Scalars['DateTime']>;
|
||||||
createdAt?: InputMaybe<Scalars['DateTime']>;
|
createdAt?: InputMaybe<Scalars['DateTime']>;
|
||||||
id?: InputMaybe<Scalars['String']>;
|
id?: InputMaybe<Scalars['String']>;
|
||||||
pipeline: PipelineCreateNestedOneWithoutPipelineProgressesInput;
|
pipeline: PipelineCreateNestedOneWithoutPipelineProgressesInput;
|
||||||
@ -1682,8 +1692,8 @@ export type PipelineProgressOrderByRelationAggregateInput = {
|
|||||||
};
|
};
|
||||||
|
|
||||||
export type PipelineProgressOrderByWithRelationInput = {
|
export type PipelineProgressOrderByWithRelationInput = {
|
||||||
amount?: InputMaybe<SortOrderInput>;
|
amount?: InputMaybe<SortOrder>;
|
||||||
closeDate?: InputMaybe<SortOrderInput>;
|
closeDate?: InputMaybe<SortOrder>;
|
||||||
createdAt?: InputMaybe<SortOrder>;
|
createdAt?: InputMaybe<SortOrder>;
|
||||||
id?: InputMaybe<SortOrder>;
|
id?: InputMaybe<SortOrder>;
|
||||||
pipeline?: InputMaybe<PipelineOrderByWithRelationInput>;
|
pipeline?: InputMaybe<PipelineOrderByWithRelationInput>;
|
||||||
@ -1714,6 +1724,7 @@ export type PipelineProgressScalarWhereInput = {
|
|||||||
NOT?: InputMaybe<Array<PipelineProgressScalarWhereInput>>;
|
NOT?: InputMaybe<Array<PipelineProgressScalarWhereInput>>;
|
||||||
OR?: InputMaybe<Array<PipelineProgressScalarWhereInput>>;
|
OR?: InputMaybe<Array<PipelineProgressScalarWhereInput>>;
|
||||||
amount?: InputMaybe<IntNullableFilter>;
|
amount?: InputMaybe<IntNullableFilter>;
|
||||||
|
closeDate?: InputMaybe<DateTimeNullableFilter>;
|
||||||
createdAt?: InputMaybe<DateTimeFilter>;
|
createdAt?: InputMaybe<DateTimeFilter>;
|
||||||
id?: InputMaybe<StringFilter>;
|
id?: InputMaybe<StringFilter>;
|
||||||
pipelineId?: InputMaybe<StringFilter>;
|
pipelineId?: InputMaybe<StringFilter>;
|
||||||
@ -1737,6 +1748,7 @@ export type PipelineProgressUpdateInput = {
|
|||||||
|
|
||||||
export type PipelineProgressUpdateManyMutationInput = {
|
export type PipelineProgressUpdateManyMutationInput = {
|
||||||
amount?: InputMaybe<NullableIntFieldUpdateOperationsInput>;
|
amount?: InputMaybe<NullableIntFieldUpdateOperationsInput>;
|
||||||
|
closeDate?: InputMaybe<NullableDateTimeFieldUpdateOperationsInput>;
|
||||||
createdAt?: InputMaybe<DateTimeFieldUpdateOperationsInput>;
|
createdAt?: InputMaybe<DateTimeFieldUpdateOperationsInput>;
|
||||||
id?: InputMaybe<StringFieldUpdateOperationsInput>;
|
id?: InputMaybe<StringFieldUpdateOperationsInput>;
|
||||||
progressableId?: InputMaybe<StringFieldUpdateOperationsInput>;
|
progressableId?: InputMaybe<StringFieldUpdateOperationsInput>;
|
||||||
@ -1818,6 +1830,7 @@ export type PipelineProgressUpdateWithWhereUniqueWithoutWorkspaceInput = {
|
|||||||
|
|
||||||
export type PipelineProgressUpdateWithoutPipelineInput = {
|
export type PipelineProgressUpdateWithoutPipelineInput = {
|
||||||
amount?: InputMaybe<NullableIntFieldUpdateOperationsInput>;
|
amount?: InputMaybe<NullableIntFieldUpdateOperationsInput>;
|
||||||
|
closeDate?: InputMaybe<NullableDateTimeFieldUpdateOperationsInput>;
|
||||||
createdAt?: InputMaybe<DateTimeFieldUpdateOperationsInput>;
|
createdAt?: InputMaybe<DateTimeFieldUpdateOperationsInput>;
|
||||||
id?: InputMaybe<StringFieldUpdateOperationsInput>;
|
id?: InputMaybe<StringFieldUpdateOperationsInput>;
|
||||||
pipelineStage?: InputMaybe<PipelineStageUpdateOneRequiredWithoutPipelineProgressesNestedInput>;
|
pipelineStage?: InputMaybe<PipelineStageUpdateOneRequiredWithoutPipelineProgressesNestedInput>;
|
||||||
@ -1828,6 +1841,7 @@ export type PipelineProgressUpdateWithoutPipelineInput = {
|
|||||||
|
|
||||||
export type PipelineProgressUpdateWithoutPipelineStageInput = {
|
export type PipelineProgressUpdateWithoutPipelineStageInput = {
|
||||||
amount?: InputMaybe<NullableIntFieldUpdateOperationsInput>;
|
amount?: InputMaybe<NullableIntFieldUpdateOperationsInput>;
|
||||||
|
closeDate?: InputMaybe<NullableDateTimeFieldUpdateOperationsInput>;
|
||||||
createdAt?: InputMaybe<DateTimeFieldUpdateOperationsInput>;
|
createdAt?: InputMaybe<DateTimeFieldUpdateOperationsInput>;
|
||||||
id?: InputMaybe<StringFieldUpdateOperationsInput>;
|
id?: InputMaybe<StringFieldUpdateOperationsInput>;
|
||||||
pipeline?: InputMaybe<PipelineUpdateOneRequiredWithoutPipelineProgressesNestedInput>;
|
pipeline?: InputMaybe<PipelineUpdateOneRequiredWithoutPipelineProgressesNestedInput>;
|
||||||
@ -1838,6 +1852,7 @@ export type PipelineProgressUpdateWithoutPipelineStageInput = {
|
|||||||
|
|
||||||
export type PipelineProgressUpdateWithoutWorkspaceInput = {
|
export type PipelineProgressUpdateWithoutWorkspaceInput = {
|
||||||
amount?: InputMaybe<NullableIntFieldUpdateOperationsInput>;
|
amount?: InputMaybe<NullableIntFieldUpdateOperationsInput>;
|
||||||
|
closeDate?: InputMaybe<NullableDateTimeFieldUpdateOperationsInput>;
|
||||||
createdAt?: InputMaybe<DateTimeFieldUpdateOperationsInput>;
|
createdAt?: InputMaybe<DateTimeFieldUpdateOperationsInput>;
|
||||||
id?: InputMaybe<StringFieldUpdateOperationsInput>;
|
id?: InputMaybe<StringFieldUpdateOperationsInput>;
|
||||||
pipeline?: InputMaybe<PipelineUpdateOneRequiredWithoutPipelineProgressesNestedInput>;
|
pipeline?: InputMaybe<PipelineUpdateOneRequiredWithoutPipelineProgressesNestedInput>;
|
||||||
@ -2356,11 +2371,6 @@ export enum SortOrder {
|
|||||||
Desc = 'desc'
|
Desc = 'desc'
|
||||||
}
|
}
|
||||||
|
|
||||||
export type SortOrderInput = {
|
|
||||||
nulls?: InputMaybe<NullsOrder>;
|
|
||||||
sort: SortOrder;
|
|
||||||
};
|
|
||||||
|
|
||||||
export type StringFieldUpdateOperationsInput = {
|
export type StringFieldUpdateOperationsInput = {
|
||||||
set?: InputMaybe<Scalars['String']>;
|
set?: InputMaybe<Scalars['String']>;
|
||||||
};
|
};
|
||||||
@ -2395,6 +2405,12 @@ export type StringNullableFilter = {
|
|||||||
startsWith?: InputMaybe<Scalars['String']>;
|
startsWith?: InputMaybe<Scalars['String']>;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
export type Telemetry = {
|
||||||
|
__typename?: 'Telemetry';
|
||||||
|
anonymizationEnabled: Scalars['Boolean'];
|
||||||
|
enabled: Scalars['Boolean'];
|
||||||
|
};
|
||||||
|
|
||||||
export type User = {
|
export type User = {
|
||||||
__typename?: 'User';
|
__typename?: 'User';
|
||||||
avatarUrl?: Maybe<Scalars['String']>;
|
avatarUrl?: Maybe<Scalars['String']>;
|
||||||
@ -2476,7 +2492,7 @@ export type UserCreateWithoutWorkspaceMemberInput = {
|
|||||||
};
|
};
|
||||||
|
|
||||||
export type UserOrderByWithRelationInput = {
|
export type UserOrderByWithRelationInput = {
|
||||||
avatarUrl?: InputMaybe<SortOrderInput>;
|
avatarUrl?: InputMaybe<SortOrder>;
|
||||||
comments?: InputMaybe<CommentOrderByRelationAggregateInput>;
|
comments?: InputMaybe<CommentOrderByRelationAggregateInput>;
|
||||||
companies?: InputMaybe<CompanyOrderByRelationAggregateInput>;
|
companies?: InputMaybe<CompanyOrderByRelationAggregateInput>;
|
||||||
createdAt?: InputMaybe<SortOrder>;
|
createdAt?: InputMaybe<SortOrder>;
|
||||||
@ -2486,10 +2502,10 @@ export type UserOrderByWithRelationInput = {
|
|||||||
firstName?: InputMaybe<SortOrder>;
|
firstName?: InputMaybe<SortOrder>;
|
||||||
id?: InputMaybe<SortOrder>;
|
id?: InputMaybe<SortOrder>;
|
||||||
lastName?: InputMaybe<SortOrder>;
|
lastName?: InputMaybe<SortOrder>;
|
||||||
lastSeen?: InputMaybe<SortOrderInput>;
|
lastSeen?: InputMaybe<SortOrder>;
|
||||||
locale?: InputMaybe<SortOrder>;
|
locale?: InputMaybe<SortOrder>;
|
||||||
metadata?: InputMaybe<SortOrderInput>;
|
metadata?: InputMaybe<SortOrder>;
|
||||||
phoneNumber?: InputMaybe<SortOrderInput>;
|
phoneNumber?: InputMaybe<SortOrder>;
|
||||||
updatedAt?: InputMaybe<SortOrder>;
|
updatedAt?: InputMaybe<SortOrder>;
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -2766,11 +2782,6 @@ export type CreateEventMutationVariables = Exact<{
|
|||||||
|
|
||||||
export type CreateEventMutation = { __typename?: 'Mutation', createEvent: { __typename?: 'Analytics', success: boolean } };
|
export type CreateEventMutation = { __typename?: 'Mutation', createEvent: { __typename?: 'Analytics', success: boolean } };
|
||||||
|
|
||||||
export type GetClientConfigQueryVariables = Exact<{ [key: string]: never; }>;
|
|
||||||
|
|
||||||
|
|
||||||
export type GetClientConfigQuery = { __typename?: 'Query', clientConfig: { __typename?: 'ClientConfig', display_google_login: boolean, prefill_login_with_seed: boolean } };
|
|
||||||
|
|
||||||
export type ChallengeMutationVariables = Exact<{
|
export type ChallengeMutationVariables = Exact<{
|
||||||
email: Scalars['String'];
|
email: Scalars['String'];
|
||||||
password: Scalars['String'];
|
password: Scalars['String'];
|
||||||
@ -2793,6 +2804,11 @@ export type RenewTokenMutationVariables = Exact<{
|
|||||||
|
|
||||||
export type RenewTokenMutation = { __typename?: 'Mutation', renewToken: { __typename?: 'AuthTokens', tokens: { __typename?: 'AuthTokenPair', accessToken: { __typename?: 'AuthToken', expiresAt: string, token: string }, refreshToken: { __typename?: 'AuthToken', token: string, expiresAt: string } } } };
|
export type RenewTokenMutation = { __typename?: 'Mutation', renewToken: { __typename?: 'AuthTokens', tokens: { __typename?: 'AuthTokenPair', accessToken: { __typename?: 'AuthToken', expiresAt: string, token: string }, refreshToken: { __typename?: 'AuthToken', token: string, expiresAt: string } } } };
|
||||||
|
|
||||||
|
export type GetClientConfigQueryVariables = Exact<{ [key: string]: never; }>;
|
||||||
|
|
||||||
|
|
||||||
|
export type GetClientConfigQuery = { __typename?: 'Query', clientConfig: { __typename?: 'ClientConfig', demoMode: boolean, debugMode: boolean, authProviders: { __typename?: 'AuthProviders', google: boolean, password: boolean }, telemetry: { __typename?: 'Telemetry', enabled: boolean, anonymizationEnabled: boolean } } };
|
||||||
|
|
||||||
export type CreateCommentMutationVariables = Exact<{
|
export type CreateCommentMutationVariables = Exact<{
|
||||||
commentId: Scalars['String'];
|
commentId: Scalars['String'];
|
||||||
commentText: Scalars['String'];
|
commentText: Scalars['String'];
|
||||||
@ -2954,7 +2970,7 @@ export type UpdateOnePipelineProgressMutationVariables = Exact<{
|
|||||||
}>;
|
}>;
|
||||||
|
|
||||||
|
|
||||||
export type UpdateOnePipelineProgressMutation = { __typename?: 'Mutation', updateOnePipelineProgress?: { __typename?: 'PipelineProgress', id: string } | null };
|
export type UpdateOnePipelineProgressMutation = { __typename?: 'Mutation', updateOnePipelineProgress?: { __typename?: 'PipelineProgress', id: string, amount?: number | null, closeDate?: string | null } | null };
|
||||||
|
|
||||||
export type UpdateOnePipelineProgressStageMutationVariables = Exact<{
|
export type UpdateOnePipelineProgressStageMutationVariables = Exact<{
|
||||||
id?: InputMaybe<Scalars['String']>;
|
id?: InputMaybe<Scalars['String']>;
|
||||||
@ -3074,41 +3090,6 @@ export function useCreateEventMutation(baseOptions?: Apollo.MutationHookOptions<
|
|||||||
export type CreateEventMutationHookResult = ReturnType<typeof useCreateEventMutation>;
|
export type CreateEventMutationHookResult = ReturnType<typeof useCreateEventMutation>;
|
||||||
export type CreateEventMutationResult = Apollo.MutationResult<CreateEventMutation>;
|
export type CreateEventMutationResult = Apollo.MutationResult<CreateEventMutation>;
|
||||||
export type CreateEventMutationOptions = Apollo.BaseMutationOptions<CreateEventMutation, CreateEventMutationVariables>;
|
export type CreateEventMutationOptions = Apollo.BaseMutationOptions<CreateEventMutation, CreateEventMutationVariables>;
|
||||||
export const GetClientConfigDocument = gql`
|
|
||||||
query GetClientConfig {
|
|
||||||
clientConfig {
|
|
||||||
display_google_login
|
|
||||||
prefill_login_with_seed
|
|
||||||
}
|
|
||||||
}
|
|
||||||
`;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* __useGetClientConfigQuery__
|
|
||||||
*
|
|
||||||
* To run a query within a React component, call `useGetClientConfigQuery` and pass it any options that fit your needs.
|
|
||||||
* When your component renders, `useGetClientConfigQuery` 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 } = useGetClientConfigQuery({
|
|
||||||
* variables: {
|
|
||||||
* },
|
|
||||||
* });
|
|
||||||
*/
|
|
||||||
export function useGetClientConfigQuery(baseOptions?: Apollo.QueryHookOptions<GetClientConfigQuery, GetClientConfigQueryVariables>) {
|
|
||||||
const options = {...defaultOptions, ...baseOptions}
|
|
||||||
return Apollo.useQuery<GetClientConfigQuery, GetClientConfigQueryVariables>(GetClientConfigDocument, options);
|
|
||||||
}
|
|
||||||
export function useGetClientConfigLazyQuery(baseOptions?: Apollo.LazyQueryHookOptions<GetClientConfigQuery, GetClientConfigQueryVariables>) {
|
|
||||||
const options = {...defaultOptions, ...baseOptions}
|
|
||||||
return Apollo.useLazyQuery<GetClientConfigQuery, GetClientConfigQueryVariables>(GetClientConfigDocument, options);
|
|
||||||
}
|
|
||||||
export type GetClientConfigQueryHookResult = ReturnType<typeof useGetClientConfigQuery>;
|
|
||||||
export type GetClientConfigLazyQueryHookResult = ReturnType<typeof useGetClientConfigLazyQuery>;
|
|
||||||
export type GetClientConfigQueryResult = Apollo.QueryResult<GetClientConfigQuery, GetClientConfigQueryVariables>;
|
|
||||||
export const ChallengeDocument = gql`
|
export const ChallengeDocument = gql`
|
||||||
mutation Challenge($email: String!, $password: String!) {
|
mutation Challenge($email: String!, $password: String!) {
|
||||||
challenge(email: $email, password: $password) {
|
challenge(email: $email, password: $password) {
|
||||||
@ -3246,6 +3227,49 @@ export function useRenewTokenMutation(baseOptions?: Apollo.MutationHookOptions<R
|
|||||||
export type RenewTokenMutationHookResult = ReturnType<typeof useRenewTokenMutation>;
|
export type RenewTokenMutationHookResult = ReturnType<typeof useRenewTokenMutation>;
|
||||||
export type RenewTokenMutationResult = Apollo.MutationResult<RenewTokenMutation>;
|
export type RenewTokenMutationResult = Apollo.MutationResult<RenewTokenMutation>;
|
||||||
export type RenewTokenMutationOptions = Apollo.BaseMutationOptions<RenewTokenMutation, RenewTokenMutationVariables>;
|
export type RenewTokenMutationOptions = Apollo.BaseMutationOptions<RenewTokenMutation, RenewTokenMutationVariables>;
|
||||||
|
export const GetClientConfigDocument = gql`
|
||||||
|
query GetClientConfig {
|
||||||
|
clientConfig {
|
||||||
|
authProviders {
|
||||||
|
google
|
||||||
|
password
|
||||||
|
}
|
||||||
|
demoMode
|
||||||
|
debugMode
|
||||||
|
telemetry {
|
||||||
|
enabled
|
||||||
|
anonymizationEnabled
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
`;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* __useGetClientConfigQuery__
|
||||||
|
*
|
||||||
|
* To run a query within a React component, call `useGetClientConfigQuery` and pass it any options that fit your needs.
|
||||||
|
* When your component renders, `useGetClientConfigQuery` 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 } = useGetClientConfigQuery({
|
||||||
|
* variables: {
|
||||||
|
* },
|
||||||
|
* });
|
||||||
|
*/
|
||||||
|
export function useGetClientConfigQuery(baseOptions?: Apollo.QueryHookOptions<GetClientConfigQuery, GetClientConfigQueryVariables>) {
|
||||||
|
const options = {...defaultOptions, ...baseOptions}
|
||||||
|
return Apollo.useQuery<GetClientConfigQuery, GetClientConfigQueryVariables>(GetClientConfigDocument, options);
|
||||||
|
}
|
||||||
|
export function useGetClientConfigLazyQuery(baseOptions?: Apollo.LazyQueryHookOptions<GetClientConfigQuery, GetClientConfigQueryVariables>) {
|
||||||
|
const options = {...defaultOptions, ...baseOptions}
|
||||||
|
return Apollo.useLazyQuery<GetClientConfigQuery, GetClientConfigQueryVariables>(GetClientConfigDocument, options);
|
||||||
|
}
|
||||||
|
export type GetClientConfigQueryHookResult = ReturnType<typeof useGetClientConfigQuery>;
|
||||||
|
export type GetClientConfigLazyQueryHookResult = ReturnType<typeof useGetClientConfigLazyQuery>;
|
||||||
|
export type GetClientConfigQueryResult = Apollo.QueryResult<GetClientConfigQuery, GetClientConfigQueryVariables>;
|
||||||
export const CreateCommentDocument = gql`
|
export const CreateCommentDocument = gql`
|
||||||
mutation CreateComment($commentId: String!, $commentText: String!, $authorId: String!, $commentThreadId: String!, $createdAt: DateTime!) {
|
mutation CreateComment($commentId: String!, $commentText: String!, $authorId: String!, $commentThreadId: String!, $createdAt: DateTime!) {
|
||||||
createOneComment(
|
createOneComment(
|
||||||
@ -4016,6 +4040,8 @@ export const UpdateOnePipelineProgressDocument = gql`
|
|||||||
data: {amount: {set: $amount}, closeDate: {set: $closeDate}}
|
data: {amount: {set: $amount}, closeDate: {set: $closeDate}}
|
||||||
) {
|
) {
|
||||||
id
|
id
|
||||||
|
amount
|
||||||
|
closeDate
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
`;
|
`;
|
||||||
|
|||||||
@ -8,7 +8,7 @@ import { ThemeType } from '@/ui/themes/themes';
|
|||||||
import '@emotion/react';
|
import '@emotion/react';
|
||||||
|
|
||||||
import { ApolloProvider } from './providers/apollo/ApolloProvider';
|
import { ApolloProvider } from './providers/apollo/ApolloProvider';
|
||||||
import { ClientConfigProvider } from './providers/clientConfig/ClientConfigProvider';
|
import { ClientConfigProvider } from './providers/client-config/ClientConfigProvider';
|
||||||
import { AppThemeProvider } from './providers/theme/AppThemeProvider';
|
import { AppThemeProvider } from './providers/theme/AppThemeProvider';
|
||||||
import { UserProvider } from './providers/user/UserProvider';
|
import { UserProvider } from './providers/user/UserProvider';
|
||||||
import { App } from './App';
|
import { App } from './App';
|
||||||
@ -26,11 +26,11 @@ root.render(
|
|||||||
<AppThemeProvider>
|
<AppThemeProvider>
|
||||||
<StrictMode>
|
<StrictMode>
|
||||||
<UserProvider>
|
<UserProvider>
|
||||||
<BrowserRouter>
|
<ClientConfigProvider>
|
||||||
<ClientConfigProvider>
|
<BrowserRouter>
|
||||||
<App />
|
<App />
|
||||||
</ClientConfigProvider>
|
</BrowserRouter>
|
||||||
</BrowserRouter>
|
</ClientConfigProvider>
|
||||||
</UserProvider>
|
</UserProvider>
|
||||||
</StrictMode>
|
</StrictMode>
|
||||||
</AppThemeProvider>
|
</AppThemeProvider>
|
||||||
|
|||||||
@ -1,9 +1,9 @@
|
|||||||
import { useCallback } from 'react';
|
import { useCallback } from 'react';
|
||||||
|
import { useRecoilState } from 'recoil';
|
||||||
|
|
||||||
|
import { telemetryState } from '@/client-config/states/telemetryState';
|
||||||
import { useCreateEventMutation } from '~/generated/graphql';
|
import { useCreateEventMutation } from '~/generated/graphql';
|
||||||
|
|
||||||
import { useIsTelemetryEnabled } from './useIsTelemetryEnabled';
|
|
||||||
|
|
||||||
interface EventLocation {
|
interface EventLocation {
|
||||||
pathname: string;
|
pathname: string;
|
||||||
}
|
}
|
||||||
@ -13,12 +13,12 @@ export interface EventData {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export function useEventTracker() {
|
export function useEventTracker() {
|
||||||
const telemetryEnabled = useIsTelemetryEnabled();
|
const [telemetry] = useRecoilState(telemetryState);
|
||||||
const [createEventMutation] = useCreateEventMutation();
|
const [createEventMutation] = useCreateEventMutation();
|
||||||
|
|
||||||
return useCallback(
|
return useCallback(
|
||||||
(eventType: string, eventData: EventData) => {
|
(eventType: string, eventData: EventData) => {
|
||||||
if (telemetryEnabled) {
|
if (telemetry.enabled) {
|
||||||
createEventMutation({
|
createEventMutation({
|
||||||
variables: {
|
variables: {
|
||||||
type: eventType,
|
type: eventType,
|
||||||
@ -27,6 +27,6 @@ export function useEventTracker() {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
[createEventMutation, telemetryEnabled],
|
[createEventMutation, telemetry],
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,4 +0,0 @@
|
|||||||
export function useIsTelemetryEnabled() {
|
|
||||||
// TODO: replace by clientConfig
|
|
||||||
return process.env.IS_TELEMETRY_ENABLED !== 'false';
|
|
||||||
}
|
|
||||||
@ -8,6 +8,7 @@ import { useRecoilState } from 'recoil';
|
|||||||
|
|
||||||
import { isMockModeState } from '@/auth/states/isMockModeState';
|
import { isMockModeState } from '@/auth/states/isMockModeState';
|
||||||
import { tokenPairState } from '@/auth/states/tokenPairState';
|
import { tokenPairState } from '@/auth/states/tokenPairState';
|
||||||
|
import { isDebugModeState } from '@/client-config/states/isDebugModeState';
|
||||||
import { CommentThreadTarget } from '~/generated/graphql';
|
import { CommentThreadTarget } from '~/generated/graphql';
|
||||||
import { mockedCompaniesData } from '~/testing/mock-data/companies';
|
import { mockedCompaniesData } from '~/testing/mock-data/companies';
|
||||||
import { mockedUsersData } from '~/testing/mock-data/users';
|
import { mockedUsersData } from '~/testing/mock-data/users';
|
||||||
@ -16,6 +17,7 @@ import { ApolloFactory } from '../services/apollo.factory';
|
|||||||
|
|
||||||
export function useApolloFactory() {
|
export function useApolloFactory() {
|
||||||
const apolloRef = useRef<ApolloFactory<NormalizedCacheObject> | null>(null);
|
const apolloRef = useRef<ApolloFactory<NormalizedCacheObject> | null>(null);
|
||||||
|
const [isDebugMode] = useRecoilState(isDebugModeState);
|
||||||
|
|
||||||
const [tokenPair, setTokenPair] = useRecoilState(tokenPairState);
|
const [tokenPair, setTokenPair] = useRecoilState(tokenPairState);
|
||||||
const [isMockMode] = useRecoilState(isMockModeState);
|
const [isMockMode] = useRecoilState(isMockModeState);
|
||||||
@ -64,10 +66,11 @@ export function useApolloFactory() {
|
|||||||
setTokenPair(null);
|
setTokenPair(null);
|
||||||
},
|
},
|
||||||
extraLinks: isMockMode ? [mockLink] : [],
|
extraLinks: isMockMode ? [mockLink] : [],
|
||||||
|
isDebugMode,
|
||||||
});
|
});
|
||||||
|
|
||||||
return apolloRef.current.getClient();
|
return apolloRef.current.getClient();
|
||||||
}, [isMockMode, setTokenPair]);
|
}, [isMockMode, setTokenPair, isDebugMode]);
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (apolloRef.current) {
|
if (apolloRef.current) {
|
||||||
|
|||||||
@ -29,6 +29,7 @@ export interface Options<TCacheShape> extends ApolloClientOptions<TCacheShape> {
|
|||||||
onTokenPairChange?: (tokenPair: AuthTokenPair) => void;
|
onTokenPairChange?: (tokenPair: AuthTokenPair) => void;
|
||||||
onUnauthenticatedError?: () => void;
|
onUnauthenticatedError?: () => void;
|
||||||
extraLinks?: ApolloLink[];
|
extraLinks?: ApolloLink[];
|
||||||
|
isDebugMode?: boolean;
|
||||||
}
|
}
|
||||||
|
|
||||||
export class ApolloFactory<TCacheShape> implements ApolloManager<TCacheShape> {
|
export class ApolloFactory<TCacheShape> implements ApolloManager<TCacheShape> {
|
||||||
@ -43,6 +44,7 @@ export class ApolloFactory<TCacheShape> implements ApolloManager<TCacheShape> {
|
|||||||
onTokenPairChange,
|
onTokenPairChange,
|
||||||
onUnauthenticatedError,
|
onUnauthenticatedError,
|
||||||
extraLinks,
|
extraLinks,
|
||||||
|
isDebugMode,
|
||||||
...options
|
...options
|
||||||
} = opts;
|
} = opts;
|
||||||
|
|
||||||
@ -98,7 +100,7 @@ export class ApolloFactory<TCacheShape> implements ApolloManager<TCacheShape> {
|
|||||||
return forward(operation);
|
return forward(operation);
|
||||||
}
|
}
|
||||||
default:
|
default:
|
||||||
if (process.env.NODE_ENV === 'development') {
|
if (isDebugMode) {
|
||||||
console.warn(
|
console.warn(
|
||||||
`[GraphQL error]: Message: ${
|
`[GraphQL error]: Message: ${
|
||||||
graphQLError.message
|
graphQLError.message
|
||||||
@ -114,7 +116,7 @@ export class ApolloFactory<TCacheShape> implements ApolloManager<TCacheShape> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (networkError) {
|
if (networkError) {
|
||||||
if (process.env.NODE_ENV === 'development') {
|
if (isDebugMode) {
|
||||||
console.warn(`[Network error]: ${networkError}`);
|
console.warn(`[Network error]: ${networkError}`);
|
||||||
}
|
}
|
||||||
onNetworkError?.(networkError);
|
onNetworkError?.(networkError);
|
||||||
@ -127,8 +129,7 @@ export class ApolloFactory<TCacheShape> implements ApolloManager<TCacheShape> {
|
|||||||
errorLink,
|
errorLink,
|
||||||
authLink,
|
authLink,
|
||||||
...(extraLinks ? extraLinks : []),
|
...(extraLinks ? extraLinks : []),
|
||||||
// Only show logger in dev mode
|
isDebugMode ? logger : null,
|
||||||
process.env.NODE_ENV !== 'production' ? logger : null,
|
|
||||||
retryLink,
|
retryLink,
|
||||||
httpLink,
|
httpLink,
|
||||||
].filter(assertNotNull),
|
].filter(assertNotNull),
|
||||||
|
|||||||
@ -1,2 +1 @@
|
|||||||
export * from './select';
|
|
||||||
export * from './update';
|
export * from './update';
|
||||||
|
|||||||
@ -1,10 +0,0 @@
|
|||||||
import { gql } from '@apollo/client';
|
|
||||||
|
|
||||||
export const GET_CLIENT_CONFIG = gql`
|
|
||||||
query GetClientConfig {
|
|
||||||
clientConfig {
|
|
||||||
display_google_login
|
|
||||||
prefill_login_with_seed
|
|
||||||
}
|
|
||||||
}
|
|
||||||
`;
|
|
||||||
@ -1,6 +1,6 @@
|
|||||||
import { atom } from 'recoil';
|
import { atom } from 'recoil';
|
||||||
|
|
||||||
export const authFlowUserEmailState = atom({
|
export const authFlowUserEmailState = atom<string>({
|
||||||
key: 'authFlowUserEmailState',
|
key: 'authFlowUserEmailState',
|
||||||
default: process.env.NODE_ENV === 'development' ? 'tim@apple.dev' : '',
|
default: '',
|
||||||
});
|
});
|
||||||
|
|||||||
@ -1,6 +0,0 @@
|
|||||||
import { atom } from 'recoil';
|
|
||||||
|
|
||||||
export const displayGoogleLogin = atom<boolean>({
|
|
||||||
key: 'displayGoogleLogin',
|
|
||||||
default: true,
|
|
||||||
});
|
|
||||||
@ -1,6 +0,0 @@
|
|||||||
import { atom } from 'recoil';
|
|
||||||
|
|
||||||
export const prefillLoginWithSeed = atom<boolean>({
|
|
||||||
key: 'prefillLoginWithSeed',
|
|
||||||
default: true,
|
|
||||||
});
|
|
||||||
18
front/src/modules/client-config/queries/index.tsx
Normal file
18
front/src/modules/client-config/queries/index.tsx
Normal file
@ -0,0 +1,18 @@
|
|||||||
|
import { gql } from '@apollo/client';
|
||||||
|
|
||||||
|
export const GET_CLIENT_CONFIG = gql`
|
||||||
|
query GetClientConfig {
|
||||||
|
clientConfig {
|
||||||
|
authProviders {
|
||||||
|
google
|
||||||
|
password
|
||||||
|
}
|
||||||
|
demoMode
|
||||||
|
debugMode
|
||||||
|
telemetry {
|
||||||
|
enabled
|
||||||
|
anonymizationEnabled
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
`;
|
||||||
@ -0,0 +1,8 @@
|
|||||||
|
import { atom } from 'recoil';
|
||||||
|
|
||||||
|
import { AuthProviders } from '~/generated/graphql';
|
||||||
|
|
||||||
|
export const authProvidersState = atom<AuthProviders>({
|
||||||
|
key: 'authProvidersState',
|
||||||
|
default: { google: false, magicLink: false, password: true },
|
||||||
|
});
|
||||||
@ -0,0 +1,6 @@
|
|||||||
|
import { atom } from 'recoil';
|
||||||
|
|
||||||
|
export const isDebugModeState = atom<boolean>({
|
||||||
|
key: 'isDebugModeState',
|
||||||
|
default: false,
|
||||||
|
});
|
||||||
@ -0,0 +1,6 @@
|
|||||||
|
import { atom } from 'recoil';
|
||||||
|
|
||||||
|
export const isDemoModeState = atom<boolean>({
|
||||||
|
key: 'isDemoModeState',
|
||||||
|
default: false,
|
||||||
|
});
|
||||||
8
front/src/modules/client-config/states/telemetryState.ts
Normal file
8
front/src/modules/client-config/states/telemetryState.ts
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
import { atom } from 'recoil';
|
||||||
|
|
||||||
|
import { Telemetry } from '~/generated/graphql';
|
||||||
|
|
||||||
|
export const telemetryState = atom<Telemetry>({
|
||||||
|
key: 'telemetryState',
|
||||||
|
default: { enabled: true, anonymizationEnabled: true },
|
||||||
|
});
|
||||||
@ -12,6 +12,7 @@ import { Logo } from '@/auth/components/ui/Logo';
|
|||||||
import { Title } from '@/auth/components/ui/Title';
|
import { Title } from '@/auth/components/ui/Title';
|
||||||
import { authFlowUserEmailState } from '@/auth/states/authFlowUserEmailState';
|
import { authFlowUserEmailState } from '@/auth/states/authFlowUserEmailState';
|
||||||
import { isMockModeState } from '@/auth/states/isMockModeState';
|
import { isMockModeState } from '@/auth/states/isMockModeState';
|
||||||
|
import { authProvidersState } from '@/client-config/states/authProvidersState';
|
||||||
import { captureHotkeyTypeInFocusState } from '@/hotkeys/states/captureHotkeyTypeInFocusState';
|
import { captureHotkeyTypeInFocusState } from '@/hotkeys/states/captureHotkeyTypeInFocusState';
|
||||||
import { MainButton } from '@/ui/components/buttons/MainButton';
|
import { MainButton } from '@/ui/components/buttons/MainButton';
|
||||||
import { TextInput } from '@/ui/components/inputs/TextInput';
|
import { TextInput } from '@/ui/components/inputs/TextInput';
|
||||||
@ -36,6 +37,8 @@ export function Index() {
|
|||||||
const navigate = useNavigate();
|
const navigate = useNavigate();
|
||||||
const theme = useTheme();
|
const theme = useTheme();
|
||||||
const [, setMockMode] = useRecoilState(isMockModeState);
|
const [, setMockMode] = useRecoilState(isMockModeState);
|
||||||
|
const [authProviders] = useRecoilState(authProvidersState);
|
||||||
|
const [demoMode] = useRecoilState(authProvidersState);
|
||||||
|
|
||||||
const [authFlowUserEmail, setAuthFlowUserEmail] = useRecoilState(
|
const [authFlowUserEmail, setAuthFlowUserEmail] = useRecoilState(
|
||||||
authFlowUserEmailState,
|
authFlowUserEmailState,
|
||||||
@ -71,7 +74,14 @@ export function Index() {
|
|||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
setMockMode(true);
|
setMockMode(true);
|
||||||
setCaptureHotkeyTypeInFocus(true);
|
setCaptureHotkeyTypeInFocus(true);
|
||||||
}, [navigate, setMockMode, setCaptureHotkeyTypeInFocus]);
|
setAuthFlowUserEmail(demoMode ? 'tim@apple.dev' : '');
|
||||||
|
}, [
|
||||||
|
navigate,
|
||||||
|
setMockMode,
|
||||||
|
setCaptureHotkeyTypeInFocus,
|
||||||
|
setAuthFlowUserEmail,
|
||||||
|
demoMode,
|
||||||
|
]);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
@ -80,12 +90,14 @@ export function Index() {
|
|||||||
</AnimatedEaseIn>
|
</AnimatedEaseIn>
|
||||||
<Title animate>Welcome to Twenty</Title>
|
<Title animate>Welcome to Twenty</Title>
|
||||||
<StyledContentContainer>
|
<StyledContentContainer>
|
||||||
<MainButton
|
{authProviders.google && (
|
||||||
icon={<IconBrandGoogle size={theme.icon.size.sm} stroke={4} />}
|
<MainButton
|
||||||
title="Continue with Google"
|
icon={<IconBrandGoogle size={theme.icon.size.sm} stroke={4} />}
|
||||||
onClick={onGoogleLoginClick}
|
title="Continue with Google"
|
||||||
fullWidth
|
onClick={onGoogleLoginClick}
|
||||||
/>
|
fullWidth
|
||||||
|
/>
|
||||||
|
)}
|
||||||
{visible && (
|
{visible && (
|
||||||
<motion.div
|
<motion.div
|
||||||
initial={{ opacity: 0, height: 0 }}
|
initial={{ opacity: 0, height: 0 }}
|
||||||
|
|||||||
@ -11,6 +11,7 @@ import { Title } from '@/auth/components/ui/Title';
|
|||||||
import { useAuth } from '@/auth/hooks/useAuth';
|
import { useAuth } from '@/auth/hooks/useAuth';
|
||||||
import { authFlowUserEmailState } from '@/auth/states/authFlowUserEmailState';
|
import { authFlowUserEmailState } from '@/auth/states/authFlowUserEmailState';
|
||||||
import { isMockModeState } from '@/auth/states/isMockModeState';
|
import { isMockModeState } from '@/auth/states/isMockModeState';
|
||||||
|
import { isDemoModeState } from '@/client-config/states/isDemoModeState';
|
||||||
import { MainButton } from '@/ui/components/buttons/MainButton';
|
import { MainButton } from '@/ui/components/buttons/MainButton';
|
||||||
import { TextInput } from '@/ui/components/inputs/TextInput';
|
import { TextInput } from '@/ui/components/inputs/TextInput';
|
||||||
import { SubSectionTitle } from '@/ui/components/section-titles/SubSectionTitle';
|
import { SubSectionTitle } from '@/ui/components/section-titles/SubSectionTitle';
|
||||||
@ -48,15 +49,15 @@ const StyledErrorContainer = styled.div`
|
|||||||
|
|
||||||
export function PasswordLogin() {
|
export function PasswordLogin() {
|
||||||
const navigate = useNavigate();
|
const navigate = useNavigate();
|
||||||
|
const [isDemoMode] = useRecoilState(isDemoModeState);
|
||||||
const prefillPassword =
|
|
||||||
process.env.NODE_ENV === 'development' ? 'Applecar2025' : '';
|
|
||||||
|
|
||||||
const [authFlowUserEmail, setAuthFlowUserEmail] = useRecoilState(
|
const [authFlowUserEmail, setAuthFlowUserEmail] = useRecoilState(
|
||||||
authFlowUserEmailState,
|
authFlowUserEmailState,
|
||||||
);
|
);
|
||||||
const [, setMockMode] = useRecoilState(isMockModeState);
|
const [, setMockMode] = useRecoilState(isMockModeState);
|
||||||
const [internalPassword, setInternalPassword] = useState(prefillPassword);
|
const [internalPassword, setInternalPassword] = useState(
|
||||||
|
isDemoMode ? 'Applecar2025' : '',
|
||||||
|
);
|
||||||
const [formError, setFormError] = useState('');
|
const [formError, setFormError] = useState('');
|
||||||
|
|
||||||
const { login } = useAuth();
|
const { login } = useAuth();
|
||||||
|
|||||||
34
front/src/providers/client-config/ClientConfigProvider.tsx
Normal file
34
front/src/providers/client-config/ClientConfigProvider.tsx
Normal file
@ -0,0 +1,34 @@
|
|||||||
|
import { useEffect } from 'react';
|
||||||
|
import { useRecoilState } from 'recoil';
|
||||||
|
|
||||||
|
import { useFetchClientConfig } from '@/auth/hooks/useFetchClientConfig';
|
||||||
|
import { authProvidersState } from '@/client-config/states/authProvidersState';
|
||||||
|
import { isDebugModeState } from '@/client-config/states/isDebugModeState';
|
||||||
|
import { isDemoModeState } from '@/client-config/states/isDemoModeState';
|
||||||
|
import { telemetryState } from '@/client-config/states/telemetryState';
|
||||||
|
|
||||||
|
export const ClientConfigProvider: React.FC<React.PropsWithChildren> = ({
|
||||||
|
children,
|
||||||
|
}) => {
|
||||||
|
const [, setAuthProviders] = useRecoilState(authProvidersState);
|
||||||
|
const [, setDebugMode] = useRecoilState(isDebugModeState);
|
||||||
|
const [, setDemoMode] = useRecoilState(isDemoModeState);
|
||||||
|
const [, setTelemetry] = useRecoilState(telemetryState);
|
||||||
|
|
||||||
|
const clientConfig = useFetchClientConfig();
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
if (clientConfig) {
|
||||||
|
setAuthProviders({
|
||||||
|
google: clientConfig.authProviders.google,
|
||||||
|
password: clientConfig.authProviders.password,
|
||||||
|
magicLink: false,
|
||||||
|
});
|
||||||
|
setDebugMode(clientConfig.debugMode);
|
||||||
|
setDemoMode(clientConfig.demoMode);
|
||||||
|
setTelemetry(clientConfig.telemetry);
|
||||||
|
}
|
||||||
|
}, [clientConfig, setAuthProviders, setDebugMode, setDemoMode, setTelemetry]);
|
||||||
|
|
||||||
|
return <>{children}</>;
|
||||||
|
};
|
||||||
@ -1,21 +0,0 @@
|
|||||||
import { useEffect } from 'react';
|
|
||||||
import { useRecoilState } from 'recoil';
|
|
||||||
|
|
||||||
import { useFetchClientConfig } from '@/auth/hooks/useFetchClientConfig';
|
|
||||||
import { displayGoogleLogin } from '@/auth/states/displayGoogleLogin';
|
|
||||||
import { prefillLoginWithSeed } from '@/auth/states/prefillLoginWithSeed';
|
|
||||||
|
|
||||||
export const ClientConfigProvider: React.FC<React.PropsWithChildren> = ({
|
|
||||||
children,
|
|
||||||
}) => {
|
|
||||||
const [, setDisplayGoogleLogin] = useRecoilState(displayGoogleLogin);
|
|
||||||
const [, setPrefillLoginWithSeed] = useRecoilState(prefillLoginWithSeed);
|
|
||||||
const clientConfig = useFetchClientConfig();
|
|
||||||
|
|
||||||
useEffect(() => {
|
|
||||||
setDisplayGoogleLogin(clientConfig?.display_google_login ?? true);
|
|
||||||
setPrefillLoginWithSeed(clientConfig?.prefill_login_with_seed ?? true);
|
|
||||||
}, [setDisplayGoogleLogin, setPrefillLoginWithSeed, clientConfig]);
|
|
||||||
|
|
||||||
return <>{children}</>;
|
|
||||||
};
|
|
||||||
@ -1,5 +1,4 @@
|
|||||||
DEBUG_MODE=false
|
DEBUG_MODE=false
|
||||||
AUTH_GOOGLE_ENABLED=false
|
|
||||||
ACCESS_TOKEN_SECRET=secret_jwt
|
ACCESS_TOKEN_SECRET=secret_jwt
|
||||||
ACCESS_TOKEN_EXPIRES_IN=5m
|
ACCESS_TOKEN_EXPIRES_IN=5m
|
||||||
LOGIN_TOKEN_SECRET=secret_login_token
|
LOGIN_TOKEN_SECRET=secret_login_token
|
||||||
|
|||||||
@ -1,13 +1,21 @@
|
|||||||
import { Test, TestingModule } from '@nestjs/testing';
|
import { Test, TestingModule } from '@nestjs/testing';
|
||||||
import { AnalyticsResolver } from './analytics.resolver';
|
import { AnalyticsResolver } from './analytics.resolver';
|
||||||
import { AnalyticsService } from './analytics.service';
|
import { AnalyticsService } from './analytics.service';
|
||||||
|
import { EnvironmentService } from 'src/integrations/environment/environment.service';
|
||||||
|
|
||||||
describe('AnalyticsResolver', () => {
|
describe('AnalyticsResolver', () => {
|
||||||
let resolver: AnalyticsResolver;
|
let resolver: AnalyticsResolver;
|
||||||
|
|
||||||
beforeEach(async () => {
|
beforeEach(async () => {
|
||||||
const module: TestingModule = await Test.createTestingModule({
|
const module: TestingModule = await Test.createTestingModule({
|
||||||
providers: [AnalyticsResolver, AnalyticsService],
|
providers: [
|
||||||
|
AnalyticsResolver,
|
||||||
|
AnalyticsService,
|
||||||
|
{
|
||||||
|
provide: EnvironmentService,
|
||||||
|
useValue: {},
|
||||||
|
},
|
||||||
|
],
|
||||||
}).compile();
|
}).compile();
|
||||||
|
|
||||||
resolver = module.get<AnalyticsResolver>(AnalyticsResolver);
|
resolver = module.get<AnalyticsResolver>(AnalyticsResolver);
|
||||||
|
|||||||
@ -1,12 +1,19 @@
|
|||||||
import { Test, TestingModule } from '@nestjs/testing';
|
import { Test, TestingModule } from '@nestjs/testing';
|
||||||
import { AnalyticsService } from './analytics.service';
|
import { AnalyticsService } from './analytics.service';
|
||||||
|
import { EnvironmentService } from 'src/integrations/environment/environment.service';
|
||||||
|
|
||||||
describe('AnalyticsService', () => {
|
describe('AnalyticsService', () => {
|
||||||
let service: AnalyticsService;
|
let service: AnalyticsService;
|
||||||
|
|
||||||
beforeEach(async () => {
|
beforeEach(async () => {
|
||||||
const module: TestingModule = await Test.createTestingModule({
|
const module: TestingModule = await Test.createTestingModule({
|
||||||
providers: [AnalyticsService],
|
providers: [
|
||||||
|
AnalyticsService,
|
||||||
|
{
|
||||||
|
provide: EnvironmentService,
|
||||||
|
useValue: {},
|
||||||
|
},
|
||||||
|
],
|
||||||
}).compile();
|
}).compile();
|
||||||
|
|
||||||
service = module.get<AnalyticsService>(AnalyticsService);
|
service = module.get<AnalyticsService>(AnalyticsService);
|
||||||
|
|||||||
@ -3,12 +3,13 @@ import { User, Workspace } from '@prisma/client';
|
|||||||
import axios, { AxiosInstance } from 'axios';
|
import axios, { AxiosInstance } from 'axios';
|
||||||
import { CreateAnalyticsInput } from './dto/create-analytics.input';
|
import { CreateAnalyticsInput } from './dto/create-analytics.input';
|
||||||
import { anonymize } from 'src/utils/anonymize';
|
import { anonymize } from 'src/utils/anonymize';
|
||||||
|
import { EnvironmentService } from 'src/integrations/environment/environment.service';
|
||||||
|
|
||||||
@Injectable()
|
@Injectable()
|
||||||
export class AnalyticsService {
|
export class AnalyticsService {
|
||||||
private readonly httpService: AxiosInstance;
|
private readonly httpService: AxiosInstance;
|
||||||
|
|
||||||
constructor() {
|
constructor(private readonly environmentService: EnvironmentService) {
|
||||||
this.httpService = axios.create({
|
this.httpService = axios.create({
|
||||||
baseURL: 'https://t.twenty.com/api/v1/s2s',
|
baseURL: 'https://t.twenty.com/api/v1/s2s',
|
||||||
});
|
});
|
||||||
@ -19,15 +20,26 @@ export class AnalyticsService {
|
|||||||
user: User | undefined,
|
user: User | undefined,
|
||||||
workspace: Workspace | undefined,
|
workspace: Workspace | undefined,
|
||||||
) {
|
) {
|
||||||
if (process.env.IS_TELEMETRY_ENABLED === 'false') {
|
if (!this.environmentService.isTelemetryEnabled()) {
|
||||||
return;
|
return { success: true };
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const anonymizationEnabled =
|
||||||
|
this.environmentService.isTelemetryAnonymizationEnabled();
|
||||||
|
|
||||||
const data = {
|
const data = {
|
||||||
type: createEventInput.type,
|
type: createEventInput.type,
|
||||||
data: {
|
data: {
|
||||||
userUUID: user ? anonymize(user.id) : undefined,
|
userUUID: user
|
||||||
workspaceUUID: workspace ? anonymize(workspace.id) : undefined,
|
? anonymizationEnabled
|
||||||
|
? anonymize(user.id)
|
||||||
|
: user.id
|
||||||
|
: undefined,
|
||||||
|
workspaceUUID: workspace
|
||||||
|
? anonymizationEnabled
|
||||||
|
? anonymize(workspace.id)
|
||||||
|
: workspace.id
|
||||||
|
: undefined,
|
||||||
workspaceDomain: workspace ? workspace.domainName : undefined,
|
workspaceDomain: workspace ? workspace.domainName : undefined,
|
||||||
...createEventInput.data,
|
...createEventInput.data,
|
||||||
},
|
},
|
||||||
|
|||||||
@ -1,5 +1,5 @@
|
|||||||
import { Args, Mutation, Resolver, Query } from '@nestjs/graphql';
|
import { Args, Mutation, Resolver, Query } from '@nestjs/graphql';
|
||||||
import { AuthTokens, ClientConfig } from './dto/token.entity';
|
import { AuthTokens } from './dto/token.entity';
|
||||||
import { TokenService } from './services/token.service';
|
import { TokenService } from './services/token.service';
|
||||||
import { RefreshTokenInput } from './dto/refresh-token.input';
|
import { RefreshTokenInput } from './dto/refresh-token.input';
|
||||||
import { BadRequestException } from '@nestjs/common';
|
import { BadRequestException } from '@nestjs/common';
|
||||||
@ -61,17 +61,4 @@ export class AuthResolver {
|
|||||||
|
|
||||||
return { tokens: tokens };
|
return { tokens: tokens };
|
||||||
}
|
}
|
||||||
|
|
||||||
@Query(() => ClientConfig)
|
|
||||||
async clientConfig(): Promise<ClientConfig> {
|
|
||||||
const displayGoogleLogin = process.env.AUTH_GOOGLE_CLIENT_ID !== undefined;
|
|
||||||
const prefillLoginWithSeed = process.env.NODE_ENV === 'development';
|
|
||||||
|
|
||||||
const clientConfig: ClientConfig = {
|
|
||||||
display_google_login: displayGoogleLogin,
|
|
||||||
prefill_login_with_seed: prefillLoginWithSeed,
|
|
||||||
};
|
|
||||||
|
|
||||||
return Promise.resolve(clientConfig);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
@ -23,12 +23,3 @@ export class AuthTokens {
|
|||||||
@Field(() => AuthTokenPair)
|
@Field(() => AuthTokenPair)
|
||||||
tokens: AuthTokenPair;
|
tokens: AuthTokenPair;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ObjectType()
|
|
||||||
export class ClientConfig {
|
|
||||||
@Field(() => Boolean)
|
|
||||||
display_google_login: boolean;
|
|
||||||
|
|
||||||
@Field(() => Boolean)
|
|
||||||
prefill_login_with_seed: boolean;
|
|
||||||
}
|
|
||||||
|
|||||||
@ -7,7 +7,7 @@ import { GoogleStrategy } from '../strategies/google.auth.strategy';
|
|||||||
export class GoogleProviderEnabledGuard implements CanActivate {
|
export class GoogleProviderEnabledGuard implements CanActivate {
|
||||||
constructor(private readonly environmentService: EnvironmentService) {}
|
constructor(private readonly environmentService: EnvironmentService) {}
|
||||||
canActivate(): boolean | Promise<boolean> | Observable<boolean> {
|
canActivate(): boolean | Promise<boolean> | Observable<boolean> {
|
||||||
if (!this.environmentService.getAuthGoogleEnabled()) {
|
if (!this.environmentService.isAuthGoogleEnabled()) {
|
||||||
throw new NotFoundException('Google auth is not enabled');
|
throw new NotFoundException('Google auth is not enabled');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
37
server/src/core/client-config/client-config.entity.ts
Normal file
37
server/src/core/client-config/client-config.entity.ts
Normal file
@ -0,0 +1,37 @@
|
|||||||
|
import { Field, ObjectType } from '@nestjs/graphql';
|
||||||
|
|
||||||
|
@ObjectType()
|
||||||
|
class AuthProviders {
|
||||||
|
@Field(() => Boolean)
|
||||||
|
google: boolean;
|
||||||
|
|
||||||
|
@Field(() => Boolean)
|
||||||
|
magicLink: boolean;
|
||||||
|
|
||||||
|
@Field(() => Boolean)
|
||||||
|
password: boolean;
|
||||||
|
}
|
||||||
|
|
||||||
|
@ObjectType()
|
||||||
|
class Telemetry {
|
||||||
|
@Field(() => Boolean)
|
||||||
|
enabled: boolean;
|
||||||
|
|
||||||
|
@Field(() => Boolean)
|
||||||
|
anonymizationEnabled: boolean;
|
||||||
|
}
|
||||||
|
|
||||||
|
@ObjectType()
|
||||||
|
export class ClientConfig {
|
||||||
|
@Field(() => AuthProviders, { nullable: false })
|
||||||
|
authProviders: AuthProviders;
|
||||||
|
|
||||||
|
@Field(() => Telemetry, { nullable: false })
|
||||||
|
telemetry: Telemetry;
|
||||||
|
|
||||||
|
@Field(() => Boolean)
|
||||||
|
demoMode: boolean;
|
||||||
|
|
||||||
|
@Field(() => Boolean)
|
||||||
|
debugMode: boolean;
|
||||||
|
}
|
||||||
7
server/src/core/client-config/client-config.module.ts
Normal file
7
server/src/core/client-config/client-config.module.ts
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
import { Module } from '@nestjs/common';
|
||||||
|
import { ClientConfigResolver } from './client-config.resolver';
|
||||||
|
|
||||||
|
@Module({
|
||||||
|
providers: [ClientConfigResolver],
|
||||||
|
})
|
||||||
|
export class ClientConfigModule {}
|
||||||
25
server/src/core/client-config/client-config.resolver.spec.ts
Normal file
25
server/src/core/client-config/client-config.resolver.spec.ts
Normal file
@ -0,0 +1,25 @@
|
|||||||
|
import { Test, TestingModule } from '@nestjs/testing';
|
||||||
|
import { ClientConfigResolver } from './client-config.resolver';
|
||||||
|
import { EnvironmentService } from 'src/integrations/environment/environment.service';
|
||||||
|
|
||||||
|
describe('ClientConfigResolver', () => {
|
||||||
|
let resolver: ClientConfigResolver;
|
||||||
|
|
||||||
|
beforeEach(async () => {
|
||||||
|
const module: TestingModule = await Test.createTestingModule({
|
||||||
|
providers: [
|
||||||
|
ClientConfigResolver,
|
||||||
|
{
|
||||||
|
provide: EnvironmentService,
|
||||||
|
useValue: {},
|
||||||
|
},
|
||||||
|
],
|
||||||
|
}).compile();
|
||||||
|
|
||||||
|
resolver = module.get<ClientConfigResolver>(ClientConfigResolver);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should be defined', () => {
|
||||||
|
expect(resolver).toBeDefined();
|
||||||
|
});
|
||||||
|
});
|
||||||
28
server/src/core/client-config/client-config.resolver.ts
Normal file
28
server/src/core/client-config/client-config.resolver.ts
Normal file
@ -0,0 +1,28 @@
|
|||||||
|
import { Resolver, Query } from '@nestjs/graphql';
|
||||||
|
import { EnvironmentService } from 'src/integrations/environment/environment.service';
|
||||||
|
import { ClientConfig } from './client-config.entity';
|
||||||
|
|
||||||
|
@Resolver()
|
||||||
|
export class ClientConfigResolver {
|
||||||
|
constructor(private environmentService: EnvironmentService) {}
|
||||||
|
|
||||||
|
@Query(() => ClientConfig)
|
||||||
|
async clientConfig(): Promise<ClientConfig> {
|
||||||
|
const clientConfig: ClientConfig = {
|
||||||
|
authProviders: {
|
||||||
|
google: this.environmentService.isAuthGoogleEnabled() ?? false,
|
||||||
|
magicLink: false,
|
||||||
|
password: true,
|
||||||
|
},
|
||||||
|
telemetry: {
|
||||||
|
enabled: this.environmentService.isTelemetryEnabled() ?? false,
|
||||||
|
anonymizationEnabled:
|
||||||
|
this.environmentService.isTelemetryAnonymizationEnabled() ?? false,
|
||||||
|
},
|
||||||
|
demoMode: this.environmentService.isDemoMode() ?? false,
|
||||||
|
debugMode: this.environmentService.isDebugMode() ?? false,
|
||||||
|
};
|
||||||
|
|
||||||
|
return Promise.resolve(clientConfig);
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -8,6 +8,7 @@ import { AuthModule } from './auth/auth.module';
|
|||||||
import { WorkspaceModule } from './workspace/workspace.module';
|
import { WorkspaceModule } from './workspace/workspace.module';
|
||||||
import { AnalyticsModule } from './analytics/analytics.module';
|
import { AnalyticsModule } from './analytics/analytics.module';
|
||||||
import { FileModule } from './file/file.module';
|
import { FileModule } from './file/file.module';
|
||||||
|
import { ClientConfigModule } from './client-config/client-config.module';
|
||||||
|
|
||||||
@Module({
|
@Module({
|
||||||
imports: [
|
imports: [
|
||||||
@ -20,6 +21,7 @@ import { FileModule } from './file/file.module';
|
|||||||
WorkspaceModule,
|
WorkspaceModule,
|
||||||
AnalyticsModule,
|
AnalyticsModule,
|
||||||
FileModule,
|
FileModule,
|
||||||
|
ClientConfigModule,
|
||||||
],
|
],
|
||||||
exports: [
|
exports: [
|
||||||
AuthModule,
|
AuthModule,
|
||||||
|
|||||||
@ -19,7 +19,7 @@ export class PrismaService extends PrismaClient implements OnModuleInit {
|
|||||||
private readonly logger = new Logger(PrismaService.name);
|
private readonly logger = new Logger(PrismaService.name);
|
||||||
|
|
||||||
constructor(private readonly environmentService: EnvironmentService) {
|
constructor(private readonly environmentService: EnvironmentService) {
|
||||||
const debugMode = environmentService.getDebugMode();
|
const debugMode = environmentService.isDebugMode();
|
||||||
super({
|
super({
|
||||||
errorFormat: 'minimal',
|
errorFormat: 'minimal',
|
||||||
log: debugMode
|
log: debugMode
|
||||||
|
|||||||
@ -8,8 +8,22 @@ import { StorageType } from './interfaces/storage.interface';
|
|||||||
export class EnvironmentService {
|
export class EnvironmentService {
|
||||||
constructor(private configService: ConfigService) {}
|
constructor(private configService: ConfigService) {}
|
||||||
|
|
||||||
getDebugMode(): boolean | undefined {
|
isDebugMode(): boolean {
|
||||||
return this.configService.get<boolean>('DEBUG_MODE')!;
|
return this.configService.get<boolean>('DEBUG_MODE') ?? false;
|
||||||
|
}
|
||||||
|
|
||||||
|
isDemoMode(): boolean {
|
||||||
|
return this.configService.get<boolean>('DEMO_MODE') ?? false;
|
||||||
|
}
|
||||||
|
|
||||||
|
isTelemetryEnabled(): boolean {
|
||||||
|
return this.configService.get<boolean>('TELEMETRY_ENABLED') ?? true;
|
||||||
|
}
|
||||||
|
|
||||||
|
isTelemetryAnonymizationEnabled(): boolean | undefined {
|
||||||
|
return (
|
||||||
|
this.configService.get<boolean>('TELEMETRY_ANONYMIZATION_ENABLED') ?? true
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
getPGDatabaseUrl(): string {
|
getPGDatabaseUrl(): string {
|
||||||
@ -44,7 +58,7 @@ export class EnvironmentService {
|
|||||||
return this.configService.get<string>('FRONT_AUTH_CALLBACK_URL')!;
|
return this.configService.get<string>('FRONT_AUTH_CALLBACK_URL')!;
|
||||||
}
|
}
|
||||||
|
|
||||||
getAuthGoogleEnabled(): boolean | undefined {
|
isAuthGoogleEnabled(): boolean | undefined {
|
||||||
return this.configService.get<boolean>('AUTH_GOOGLE_ENABLED');
|
return this.configService.get<boolean>('AUTH_GOOGLE_ENABLED');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -16,12 +16,27 @@ import { IsAWSRegion } from './decorators/is-aws-region.decorator';
|
|||||||
import { CastToBoolean } from './decorators/cast-to-boolean.decorator';
|
import { CastToBoolean } from './decorators/cast-to-boolean.decorator';
|
||||||
|
|
||||||
export class EnvironmentVariables {
|
export class EnvironmentVariables {
|
||||||
// Stage
|
// Misc
|
||||||
@CastToBoolean()
|
@CastToBoolean()
|
||||||
@IsOptional()
|
@IsOptional()
|
||||||
@IsBoolean()
|
@IsBoolean()
|
||||||
DEBUG_MODE?: boolean;
|
DEBUG_MODE?: boolean;
|
||||||
|
|
||||||
|
@CastToBoolean()
|
||||||
|
@IsOptional()
|
||||||
|
@IsBoolean()
|
||||||
|
DEMO_MODE?: boolean;
|
||||||
|
|
||||||
|
@CastToBoolean()
|
||||||
|
@IsOptional()
|
||||||
|
@IsBoolean()
|
||||||
|
TELEMETRY_ENABLED?: boolean;
|
||||||
|
|
||||||
|
@CastToBoolean()
|
||||||
|
@IsOptional()
|
||||||
|
@IsBoolean()
|
||||||
|
TELEMETRY_ANONYMIZATION_ENABLED?: boolean;
|
||||||
|
|
||||||
// Database
|
// Database
|
||||||
@IsUrl({ protocols: ['postgres'], require_tld: false })
|
@IsUrl({ protocols: ['postgres'], require_tld: false })
|
||||||
PG_DATABASE_URL: string;
|
PG_DATABASE_URL: string;
|
||||||
|
|||||||
@ -1,4 +1,4 @@
|
|||||||
import { Global, Module } from '@nestjs/common';
|
import { Module } from '@nestjs/common';
|
||||||
import { fromNodeProviderChain } from '@aws-sdk/credential-providers';
|
import { fromNodeProviderChain } from '@aws-sdk/credential-providers';
|
||||||
import { EnvironmentModule } from './environment/environment.module';
|
import { EnvironmentModule } from './environment/environment.module';
|
||||||
import { EnvironmentService } from './environment/environment.service';
|
import { EnvironmentService } from './environment/environment.service';
|
||||||
|
|||||||
@ -1,9 +1,6 @@
|
|||||||
import crypto from 'crypto';
|
import crypto from 'crypto';
|
||||||
|
|
||||||
export function anonymize(input) {
|
export function anonymize(input: string) {
|
||||||
if (process.env.IS_TELEMETRY_ANONYMIZATION_ENABLED === 'false') {
|
|
||||||
return input;
|
|
||||||
}
|
|
||||||
// md5 shorter than sha-256 and collisions are not a security risk in this use-case
|
// md5 shorter than sha-256 and collisions are not a security risk in this use-case
|
||||||
return crypto.createHash('md5').update(input).digest('hex');
|
return crypto.createHash('md5').update(input).digest('hex');
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user