feat(auth): replace cms config

Because:

- Replace contentful config vars with cms and strapi config vars

This commit:

- Adds cms and cms.strapiClient config vars and updates usage in various
  locations

Closes #FXA-9980
This commit is contained in:
Reino Muhl 2024-07-30 11:41:53 -04:00
Родитель 7d3da47ae4
Коммит a35b0e0dd5
Не найден ключ, соответствующий данной подписи
13 изменённых файлов: 72 добавлений и 91 удалений

Просмотреть файл

@ -56,7 +56,7 @@ export class CartService {
ip?: string;
}): Promise<ResultCart> {
// TODO:
// - Fetch information about interval, offering, experiments from Contentful
// - Fetch information about interval, offering, experiments from CMS
// - Guess TaxAddress via maxmind client
// - Check if user is eligible to subscribe to plan, else throw error
// - Fetch stripeCustomerId if uid is passed and has a customer id

Просмотреть файл

@ -2,7 +2,7 @@
This library was generated with [Nx](https://nx.dev).
It serves as a client for communicating with the Contentful GraphQL API, and supports strongly typed queries via codegen. See the codegen section for more information about how to manage typings.
It serves as a client for communicating with the CMS GraphQL API, and supports strongly typed queries via codegen. See the codegen section for more information about how to manage typings.
## Building
@ -16,14 +16,12 @@ You can update the generated types from the Nx GraphQL API via:
`nx run shared-cms:codegen`
To run codegen, you will need to have the following four parameters present in your .env file:
To run codegen, you will need to have the following two parameters present in your .env file:
1. `CONTENTFUL_GRAPHQL_API_URL`
2. `CONTENTFUL_GRAPHQL_API_KEY`
3. `CONTENTFUL_GRAPHQL_SPACE_ID`
4. `CONTENTFUL_GRAPHQL_ENVIRONMENT`
1. `STRAPI_CLIENT_CONFIG__GRAPHQL_API_URI`
2. `STRAPI_CLIENT_CONFIG__API_KEY`
Running codegen can be done at any time, though it's most important to do so after the Contentful schema has been updated, or when adding a new query/mutation to the project. Types for queries or mutations are automatically generated by the codegen client, so that they match the associated types from Contentful.
Running codegen can be done at any time, though it's most important to do so after the CMS schema has been updated, or when adding a new query/mutation to the project. Types for queries or mutations are automatically generated by the codegen client, so that they match the associated types from the CMS.
## Running unit tests

Просмотреть файл

@ -94,7 +94,7 @@ export class PurchaseWithDetailsOfferingContentUtil {
get purchases(): PurchaseWithDetailsOfferingContentByPlanIdsResult['purchases'] {
// Deduplicating items as there could be duplicates from splitting up the
// stripePlanIds and making multiple Contentful calls
// stripePlanIds and making multiple CMS calls
return {
data: [
...new Map(

Просмотреть файл

@ -20,7 +20,7 @@ import {
import { determineLocale } from '@fxa/shared/l10n';
import { DEFAULT_LOCALE } from './constants';
import { CMSError } from './cms.error';
import { CONTENTFUL_QUERY_CACHE_KEY, cacheKeyForQuery } from './util';
import { CMS_QUERY_CACHE_KEY, cacheKeyForQuery } from './util';
import { StrapiClientConfig } from './strapi.client.config';
import { LocalesResult, localesQuery } from './queries/locales';
@ -63,8 +63,8 @@ export class StrapiClient {
}
async getLocale(acceptLanguage: string): Promise<string> {
const contentfulLocales = await this.getLocales();
const result = determineLocale(acceptLanguage, contentfulLocales);
const strapiLocales = await this.getLocales();
const result = determineLocale(acceptLanguage, strapiLocales);
if (result === 'en') {
return DEFAULT_LOCALE;
}
@ -81,7 +81,7 @@ export class StrapiClient {
// new FirestoreAdapter(
// context.firestore,
// context.strapiClientConfig.firestoreCacheCollectionName ||
// CONTENTFUL_QUERY_CACHE_KEY
// CMS_QUERY_CACHE_KEY
// ),
// })
async query<Result, Variables extends OperationVariables>(

Просмотреть файл

@ -5,7 +5,7 @@
import type { OperationVariables, TypedDocumentNode } from '@apollo/client';
import { createHash } from 'crypto';
export const CONTENTFUL_QUERY_CACHE_KEY = 'contentfulQueryCache';
export const CMS_QUERY_CACHE_KEY = 'cmsQueryCache';
export const cacheKeyForQuery = function <
Result,
@ -22,5 +22,5 @@ export const cacheKeyForQuery = function <
const variableHash = createHash('sha256')
.update(variablesString)
.digest('hex');
return `${CONTENTFUL_QUERY_CACHE_KEY}:${queryHash}:${variableHash}`;
return `${CMS_QUERY_CACHE_KEY}:${queryHash}:${variableHash}`;
};

Просмотреть файл

@ -577,12 +577,12 @@ const conf = convict({
env: 'NEWSLETTER_HOST',
},
},
contentful: {
cms: {
enabled: {
doc: 'Whether to use Contentful',
doc: 'Whether to use CMS',
format: Boolean,
default: false,
env: 'CONTENTFUL_ENABLED',
env: 'CMS_ENABLED',
},
},
cloudTasks: CloudTasksConvictConfigFactory(),

Просмотреть файл

@ -132,7 +132,7 @@ export class StripeService extends StripeHelper {
authFirestore: configService.get('authFirestore'),
subhub: configService.get('subhub'),
redis: configService.get('redis'),
contentful: configService.get('contentful'),
cms: configService.get('cms'),
};
super(config, metrics, logger);

Просмотреть файл

@ -142,28 +142,15 @@ async function run(config) {
);
Container.set(PromotionCodeManager, promotionCodeManager);
if (
config.contentful &&
config.contentful.cdnUrl &&
config.contentful.graphqlUrl &&
config.contentful.apiKey &&
config.contentful.spaceId &&
config.contentful.environment &&
config.contentful.firestoreCacheCollectionName
) {
if (config.cms.enabled) {
const strapiClientConfig = config.cms.strapiClient;
const { graphqlApiUri, apiKey, firestoreCacheCollectionName } =
strapiClientConfig;
if (!(graphqlApiUri && apiKey && firestoreCacheCollectionName)) {
throw new Error('Missing required configuration for CMS Strapi Client');
}
const firestore = Container.get(AuthFirestore);
const strapiClient = new StrapiClient(
{
cdnApiUri: config.contentful.cdnUrl,
graphqlApiUri: config.contentful.graphqlUrl,
graphqlApiKey: config.contentful.apiKey,
graphqlSpaceId: config.contentful.spaceId,
graphqlEnvironment: config.contentful.environment,
firestoreCacheCollectionName:
config.contentful.firestoreCacheCollectionName,
},
firestore
);
const strapiClient = new StrapiClient(strapiClientConfig, firestore);
const productConfigurationManager = new ProductConfigurationManager(
strapiClient,
statsd

Просмотреть файл

@ -2001,49 +2001,45 @@ const convictConf = convict({
env: 'CERTIFICATE_SIGN_DISABLE_ROLLOUT_RATE',
format: Number,
},
contentful: {
cdnUrl: {
doc: 'Base URL for Content Delivery API (https://www.contentful.com/developers/docs/references/content-delivery-api/)',
format: String,
env: 'CONTENTFUL_CDN_API_URL',
default: '',
},
graphqlUrl: {
default: '',
doc: 'Base URL for GraphQL Content API (https://www.contentful.com/developers/docs/references/graphql/)',
env: 'CONTENTFUL_GRAPHQL_API_URL',
format: String,
},
apiKey: {
default: '',
doc: 'GraphQL Content API key for Contentful hCMS to fetch RP-provided content (https://www.contentful.com/developers/docs/references/authentication/)',
env: 'CONTENTFUL_GRAPHQL_API_KEY',
format: String,
},
spaceId: {
default: '',
doc: 'Alphanumeric id used for instantiating the ContentfulClient (https://www.contentful.com/developers/docs/references/content-management-api/#/reference/spaces)',
env: 'CONTENTFUL_GRAPHQL_SPACE_ID',
format: String,
},
environment: {
default: '',
doc: 'Environment alias used for instantiating the ContentfulClient (https://www.contentful.com/developers/docs/concepts/multiple-environments/)',
env: 'CONTENTFUL_GRAPHQL_ENVIRONMENT',
format: String,
},
firestoreCacheCollectionName: {
default: 'fxa-auth-server-contentful-query-cache',
doc: 'Firestore collection name to store Contentful query cache',
env: 'CONTENTFUL_FIRESTORE_CACHE_COLLECTION_NAME',
format: String,
},
cms: {
enabled: {
default: false,
doc: 'Whether to use Contentful',
env: 'CONTENTFUL_ENABLED',
doc: 'Whether to use CMS',
env: 'CMS_ENABLED',
format: Boolean,
},
strapiClient: {
graphqlApiUri: {
default: '',
doc: 'Base URL for GraphQL API',
env: 'STRAPI_CLIENT_GRAPHQL_API_URI',
format: String,
},
apiKey: {
default: '',
doc: 'GraphQL Content API key for Strapi to fetch RP-provided content',
env: 'STRAPI_CLIENT_API_KEY',
format: String,
},
memCacheTTL: {
default: 300,
doc: 'Strapi client memory cache TTL in seconds',
env: 'STRAPI_CLIENT_MEM_CACHE_TTL',
format: Number,
},
firestoreCacheCollectionName: {
default: 'fxa-auth-server-strapi-query-cache',
doc: 'Firestore collection name to store CMS query cache',
env: 'STRAPI_CLIENT_FIRESTORE_CACHE_COLLECTION_NAME',
format: String,
},
firestoreCacheTTL: {
default: 604800,
doc: 'Strapi client Firestore cache TTL in seconds',
env: 'STRAPI_CLIENT_FIRESTORE_CACHE_TTL',
format: Number,
},
},
},
cloudTasks: CloudTasksConvictConfigFactory(),
cloudScheduler: {

Просмотреть файл

@ -324,7 +324,7 @@ export class CapabilityService {
targetPlanId: string,
useFirestoreProductConfigs = false
): Promise<SubscriptionChangeEligibility> {
const cmsEnabled = this.config.contentful.enabled;
const cmsEnabled = this.config.cms.enabled;
const allPlansByPlanId = await this.allAbbrevPlansByPlanId();
@ -892,7 +892,7 @@ export class CapabilityService {
* Retrieve the client capabilities
*/
async getClients() {
const cmsEnabled = this.config.contentful.enabled;
const cmsEnabled = this.config.cms.enabled;
if (cmsEnabled) {
if (!this.capabilityManager) {
@ -955,7 +955,7 @@ export class CapabilityService {
async planIdsToClientCapabilities(
subscribedPrices: string[]
): Promise<ClientIdCapabilityMap> {
const cmsEnabled = this.config.contentful.enabled;
const cmsEnabled = this.config.cms.enabled;
if (cmsEnabled) {
if (!this.capabilityManager) {

Просмотреть файл

@ -172,7 +172,7 @@ describe('CapabilityService', () => {
mockCMSPlanIdsToClientCapabilities
),
};
mockConfig = { ...config, contentful: { enabled: false } };
mockConfig = { ...config, cms: { enabled: false } };
log = mockLog();
Container.set(AppConfig, mockConfig);
@ -1324,7 +1324,7 @@ describe('CapabilityService', () => {
describe('CMS flag is enabled', () => {
it('returns planIdsToClientCapabilities from CMS', async () => {
mockConfig.contentful.enabled = true;
mockConfig.cms.enabled = true;
capabilityService.subscribedPriceIds = sinon.fake.resolves([UID]);
@ -1344,7 +1344,7 @@ describe('CapabilityService', () => {
});
it('returns getClients from CMS', async () => {
mockConfig.contentful.enabled = true;
mockConfig.cms.enabled = true;
const mockClientsFromCMS = await mockCapabilityManager.getClients();

Просмотреть файл

@ -146,7 +146,7 @@ const mockConfig = {
stripeTaxRatesCacheTtlSeconds: 60,
},
currenciesToCountries: { ZAR: ['AS', 'CA'] },
contentful: {
cms: {
enabled: false,
},
};
@ -3423,7 +3423,7 @@ describe('#integration - StripeHelper', () => {
});
it('returns CMS values', async () => {
const newWebIconURL = 'http://contentful.example/webicon';
const newWebIconURL = 'http://strapi.example/webicon';
const mockCMSConfigUtil = {
transformedPurchaseWithCommonContentForPlanId: (planId) => {
return PurchaseWithDetailsOfferingContentTransformedFactory({
@ -3468,7 +3468,7 @@ describe('#integration - StripeHelper', () => {
it('returns CMS values when flag is enabled', async () => {
// enable flag
mockConfig.contentful.enabled = true;
mockConfig.cms.enabled = true;
// set container
const mockProductConfigurationManager = {
@ -3493,7 +3493,7 @@ describe('#integration - StripeHelper', () => {
await stripeHelper.allAbbrevPlans();
// test that flag is enabled and all spies called
assert.isTrue(mockConfig.contentful.enabled);
assert.isTrue(mockConfig.cms.enabled);
assert(stripeHelper.allConfiguredPlans.calledOnce);
assert(stripeHelper.allPlans.calledOnce);
assert(stripeHelper.stripe.plans.list.calledOnce);

Просмотреть файл

@ -94,7 +94,7 @@ export type StripeHelperConfig = {
plansCacheTtlSeconds: number;
};
redis: any; // TODO
contentful: {
cms: {
enabled: boolean;
};
};
@ -478,7 +478,7 @@ export abstract class StripeHelper {
const validPlansMapped = await cmsToStripeMapper.mapCMSToStripePlans(
validPlans,
acceptLanguage,
this.config.contentful.enabled
this.config.cms.enabled
);
validPlansFinal.push(...validPlansMapped.mappedPlans);