From 0b13a75e35747b702fe604ccbcdc73ebb2f29dfa Mon Sep 17 00:00:00 2001 From: Danielle Adams Date: Fri, 27 Aug 2021 18:15:20 -0400 Subject: [PATCH 1/9] feat(amplify-category-api): add global sandbox mode directive on schema generation --- .../cfn-api-artifact-handler.ts | 43 ++++++++++++++++++- .../appSync-walkthrough.ts | 7 ++- .../utils/global-sandbox-mode.ts | 8 ++++ .../src/transformation/transform.ts | 5 +++ .../src/transformation/validation.ts | 1 + .../src/transformer-context/resolver.ts | 2 +- 6 files changed, 62 insertions(+), 4 deletions(-) create mode 100644 packages/amplify-category-api/src/provider-utils/awscloudformation/utils/global-sandbox-mode.ts diff --git a/packages/amplify-category-api/src/provider-utils/awscloudformation/cfn-api-artifact-handler.ts b/packages/amplify-category-api/src/provider-utils/awscloudformation/cfn-api-artifact-handler.ts index 0b4a49a2a7e..c252b633b80 100644 --- a/packages/amplify-category-api/src/provider-utils/awscloudformation/cfn-api-artifact-handler.ts +++ b/packages/amplify-category-api/src/provider-utils/awscloudformation/cfn-api-artifact-handler.ts @@ -18,6 +18,7 @@ import _ from 'lodash'; import { getAppSyncResourceName, getAppSyncAuthConfig, checkIfAuthExists, authConfigHasApiKey } from './utils/amplify-meta-utils'; import { printApiKeyWarnings } from './utils/print-api-key-warnings'; import { isNameUnique } from './utils/check-case-sensitivity'; +import { FeatureFlags } from 'amplify-cli-core'; // keep in sync with ServiceName in amplify-category-function, but probably it will not change const FunctionServiceNameLambdaFunction = 'Lambda'; @@ -90,7 +91,20 @@ class CfnApiArtifactHandler implements ApiArtifactHandler { authConfig, }); - this.context.amplify.updateamplifyMetaAfterResourceAdd(category, serviceConfig.apiName, this.createAmplifyMeta(authConfig)); + const useExperimentalPipelineTransformer = FeatureFlags.getBoolean('graphQLTransformer.useExperimentalPipelinedTransformer'); + let globalSandboxModeConfig; + + if (useExperimentalPipelineTransformer) { + const envName = this.context.amplify.getEnvInfo().envName; + globalSandboxModeConfig = {}; + globalSandboxModeConfig[envName] = { enabled: true }; + } + + this.context.amplify.updateamplifyMetaAfterResourceAdd( + category, + serviceConfig.apiName, + this.createAmplifyMeta(authConfig, globalSandboxModeConfig), + ); return serviceConfig.apiName; }; @@ -129,17 +143,42 @@ class CfnApiArtifactHandler implements ApiArtifactHandler { printApiKeyWarnings(this.context, oldConfigHadApiKey, authConfigHasApiKey(authConfig)); }; + updateArtifactsWithoutCompile = async (request: UpdateApiRequest): Promise => { + const updates = request.serviceModification; + const apiName = getAppSyncResourceName(this.context.amplify.getProjectMeta()); + if (!apiName) { + throw new Error(`No AppSync API configured in the project. Use 'amplify add api' to create an API.`); + } + const resourceDir = this.getResourceDir(apiName); + if (updates.transformSchema) { + this.writeSchema(resourceDir, updates.transformSchema); + } + if (updates.conflictResolution) { + updates.conflictResolution = await this.createResolverResources(updates.conflictResolution); + await writeResolverConfig(updates.conflictResolution, resourceDir); + } + const authConfig = getAppSyncAuthConfig(this.context.amplify.getProjectMeta()); + + if (updates.defaultAuthType) authConfig.defaultAuthentication = appSyncAuthTypeToAuthConfig(updates.defaultAuthType); + if (updates.additionalAuthTypes) + authConfig.additionalAuthenticationProviders = updates.additionalAuthTypes.map(appSyncAuthTypeToAuthConfig); + + this.context.amplify.updateamplifyMetaAfterResourceUpdate(category, apiName, 'output', { authConfig }); + this.context.amplify.updateBackendConfigAfterResourceUpdate(category, apiName, 'output', { authConfig }); + }; + private writeSchema = (resourceDir: string, schema: string) => { fs.writeFileSync(path.join(resourceDir, gqlSchemaFilename), schema); }; private getResourceDir = (apiName: string) => path.join(this.context.amplify.pathManager.getBackendDirPath(), category, apiName); - private createAmplifyMeta = authConfig => ({ + private createAmplifyMeta = (authConfig, globalSandboxModeConfig) => ({ service: 'AppSync', providerPlugin: provider, output: { authConfig, + globalSandboxModeConfig, }, }); diff --git a/packages/amplify-category-api/src/provider-utils/awscloudformation/service-walkthroughs/appSync-walkthrough.ts b/packages/amplify-category-api/src/provider-utils/awscloudformation/service-walkthroughs/appSync-walkthrough.ts index f2878dbb503..f2c3ab30a39 100644 --- a/packages/amplify-category-api/src/provider-utils/awscloudformation/service-walkthroughs/appSync-walkthrough.ts +++ b/packages/amplify-category-api/src/provider-utils/awscloudformation/service-walkthroughs/appSync-walkthrough.ts @@ -21,6 +21,8 @@ import { $TSContext, open, } from 'amplify-cli-core'; +import { defineGlobalSandboxMode } from '../utils/global-sandbox-mode'; +import { Duration, Expiration } from '@aws-cdk/core'; const serviceName = 'AppSync'; const elasticContainerServiceName = 'ElasticContainer'; @@ -208,6 +210,9 @@ export const serviceWalkthrough = async (context: $TSContext, defaultValuesFilen schemaContent = fs.readFileSync(schemaFilePath, 'utf8'); askToEdit = false; } else { + const useExperimentalPipelineTransformer = FeatureFlags.getBoolean('graphQLTransformer.useExperimentalPipelinedTransformer'); + schemaContent += useExperimentalPipelineTransformer ? defineGlobalSandboxMode(context) : ''; + // Schema template selection const templateSelectionQuestion = { type: inputs[4].type, @@ -219,7 +224,7 @@ export const serviceWalkthrough = async (context: $TSContext, defaultValuesFilen const { templateSelection } = await inquirer.prompt(templateSelectionQuestion); const schemaFilePath = path.join(graphqlSchemaDir, templateSelection); - schemaContent = fs.readFileSync(schemaFilePath, 'utf8'); + schemaContent += fs.readFileSync(schemaFilePath, 'utf8'); } return { diff --git a/packages/amplify-category-api/src/provider-utils/awscloudformation/utils/global-sandbox-mode.ts b/packages/amplify-category-api/src/provider-utils/awscloudformation/utils/global-sandbox-mode.ts new file mode 100644 index 00000000000..44aa0ec4793 --- /dev/null +++ b/packages/amplify-category-api/src/provider-utils/awscloudformation/utils/global-sandbox-mode.ts @@ -0,0 +1,8 @@ +export function defineGlobalSandboxMode(context: any): string { + const envName = context.amplify.getEnvInfo().envName; + + return `# This allows public create, read, update, and delete access for a limited time to all models via API Key. +# To configure PRODUCTION-READY authorization rules, review: https://docs.amplify.aws/cli/graphql-transformer/auth +type AMPLIFY_GLOBAL @allow_public_data_access_with_api_key(in: \"${envName}\") # FOR TESTING ONLY!\n +`; +} diff --git a/packages/amplify-graphql-transformer-core/src/transformation/transform.ts b/packages/amplify-graphql-transformer-core/src/transformation/transform.ts index 151d942f21d..2f871c98e5f 100644 --- a/packages/amplify-graphql-transformer-core/src/transformation/transform.ts +++ b/packages/amplify-graphql-transformer-core/src/transformation/transform.ts @@ -121,10 +121,15 @@ export class GraphQLTransform { aws_iam: true, aws_oidc: true, aws_cognito_user_pools: true, + allow_public_data_access_with_api_key: true, deprecated: true, }, ); let allModelDefinitions = [...context.inputDocument.definitions]; + + const ampGlobalIdx = allModelDefinitions.findIndex(el => el.kind === 'ObjectTypeDefinition' && el.name.value === 'AMPLIFY_GLOBAL'); + if (ampGlobalIdx > -1) allModelDefinitions.splice(ampGlobalIdx, 1); + for (const transformer of this.transformers) { allModelDefinitions = allModelDefinitions.concat(...transformer.typeDefinitions, transformer.directive); } diff --git a/packages/amplify-graphql-transformer-core/src/transformation/validation.ts b/packages/amplify-graphql-transformer-core/src/transformation/validation.ts index 4e94fd7b6e4..3633e8b5e7d 100644 --- a/packages/amplify-graphql-transformer-core/src/transformation/validation.ts +++ b/packages/amplify-graphql-transformer-core/src/transformation/validation.ts @@ -109,6 +109,7 @@ directive @aws_api_key on FIELD_DEFINITION | OBJECT directive @aws_iam on FIELD_DEFINITION | OBJECT directive @aws_oidc on FIELD_DEFINITION | OBJECT directive @aws_cognito_user_pools(cognito_groups: [String!]) on FIELD_DEFINITION | OBJECT +directive @allow_public_data_access_with_api_key(env: [String!]) on OBJECT # Allows transformer libraries to deprecate directive arguments. directive @deprecated(reason: String) on FIELD_DEFINITION | INPUT_FIELD_DEFINITION | ENUM | ENUM_VALUE diff --git a/packages/amplify-graphql-transformer-core/src/transformer-context/resolver.ts b/packages/amplify-graphql-transformer-core/src/transformer-context/resolver.ts index 7f24e383b86..33146d5af9c 100644 --- a/packages/amplify-graphql-transformer-core/src/transformer-context/resolver.ts +++ b/packages/amplify-graphql-transformer-core/src/transformer-context/resolver.ts @@ -210,7 +210,7 @@ export class TransformerResolver implements TransformerResolverProvider { } break; default: - throw new Error('Unknow DataSource type'); + throw new Error('Unknown DataSource type'); } } api.host.addResolver( From 23446eeefa5a55878d7813ec66c13c671f7af516 Mon Sep 17 00:00:00 2001 From: Danielle Adams Date: Fri, 27 Aug 2021 18:37:23 -0400 Subject: [PATCH 2/9] feat(cli): add sandbox mode warning to amplify status --- .../cfn-api-artifact-handler.test.ts.snap | 1 + ...p-sync-auth-type-bi-di-mapper.test.ts.snap | 2 + .../appSync-walkthrough.ts | 2 + ...nfig-to-app-sync-auth-type-bi-di-mapper.ts | 2 + packages/amplify-cli-core/src/index.ts | 5 +- .../amplify-helpers/api-key.test.ts | 78 +++++++++++++++++++ .../testData/mockLocalCloud/amplify-meta.json | 30 +++++++ packages/amplify-cli/src/commands/status.ts | 26 ++++--- .../amplify-cli/src/domain/amplify-toolkit.ts | 10 ++- .../src/extensions/amplify-helpers/api-key.ts | 51 ++++++++++++ .../amplify-helpers/push-resources.ts | 2 + .../show-global-sandbox-mode-warning.ts | 31 ++++++++ .../src/transformation/transform.ts | 13 +++- .../src/transformation/transformer-config.ts | 7 +- .../src/interface/api/add.ts | 1 + .../src/ModelAuthTransformer.ts | 11 ++- 16 files changed, 245 insertions(+), 27 deletions(-) create mode 100644 packages/amplify-cli/src/__tests__/extensions/amplify-helpers/api-key.test.ts create mode 100644 packages/amplify-cli/src/__tests__/extensions/amplify-helpers/testData/mockLocalCloud/amplify-meta.json create mode 100644 packages/amplify-cli/src/extensions/amplify-helpers/api-key.ts create mode 100644 packages/amplify-cli/src/extensions/amplify-helpers/show-global-sandbox-mode-warning.ts diff --git a/packages/amplify-category-api/src/__tests__/provider-utils/awscloudformation/__snapshots__/cfn-api-artifact-handler.test.ts.snap b/packages/amplify-category-api/src/__tests__/provider-utils/awscloudformation/__snapshots__/cfn-api-artifact-handler.test.ts.snap index 36f39965a9b..3b9aa6928f1 100644 --- a/packages/amplify-category-api/src/__tests__/provider-utils/awscloudformation/__snapshots__/cfn-api-artifact-handler.test.ts.snap +++ b/packages/amplify-category-api/src/__tests__/provider-utils/awscloudformation/__snapshots__/cfn-api-artifact-handler.test.ts.snap @@ -18,6 +18,7 @@ Object { }, Object { "apiKeyConfig": Object { + "apiKeyExpirationDate": undefined, "apiKeyExpirationDays": undefined, "description": undefined, }, diff --git a/packages/amplify-category-api/src/__tests__/provider-utils/awscloudformation/utils/__snapshots__/auth-config-to-app-sync-auth-type-bi-di-mapper.test.ts.snap b/packages/amplify-category-api/src/__tests__/provider-utils/awscloudformation/utils/__snapshots__/auth-config-to-app-sync-auth-type-bi-di-mapper.test.ts.snap index 73049e4ca95..3c18c0fa241 100644 --- a/packages/amplify-category-api/src/__tests__/provider-utils/awscloudformation/utils/__snapshots__/auth-config-to-app-sync-auth-type-bi-di-mapper.test.ts.snap +++ b/packages/amplify-category-api/src/__tests__/provider-utils/awscloudformation/utils/__snapshots__/auth-config-to-app-sync-auth-type-bi-di-mapper.test.ts.snap @@ -12,6 +12,7 @@ Object { exports[`AppSyncAuthType to authConfig maps API_KEY correctly 1`] = ` Object { "apiKeyConfig": Object { + "apiKeyExpirationDate": undefined, "apiKeyExpirationDays": 120, "description": undefined, }, @@ -47,6 +48,7 @@ Object { exports[`authConfig to AppSyncAuthType maps API_KEY auth correctly 1`] = ` Object { + "apiKeyExpirationDate": undefined, "expirationTime": 120, "keyDescription": "api key description", "mode": "API_KEY", diff --git a/packages/amplify-category-api/src/provider-utils/awscloudformation/service-walkthroughs/appSync-walkthrough.ts b/packages/amplify-category-api/src/provider-utils/awscloudformation/service-walkthroughs/appSync-walkthrough.ts index f2c3ab30a39..6d5f87e36f8 100644 --- a/packages/amplify-category-api/src/provider-utils/awscloudformation/service-walkthroughs/appSync-walkthrough.ts +++ b/packages/amplify-category-api/src/provider-utils/awscloudformation/service-walkthroughs/appSync-walkthrough.ts @@ -624,6 +624,8 @@ async function askApiKeyQuestions() { ]; const apiKeyConfig = await inquirer.prompt(apiKeyQuestions); + const apiKeyExpirationDaysNum = Number(apiKeyConfig.apiKeyExpirationDays); + apiKeyConfig.apiKeyExpirationDate = Expiration.after(Duration.days(apiKeyExpirationDaysNum)).date; return { authenticationType: 'API_KEY', diff --git a/packages/amplify-category-api/src/provider-utils/awscloudformation/utils/auth-config-to-app-sync-auth-type-bi-di-mapper.ts b/packages/amplify-category-api/src/provider-utils/awscloudformation/utils/auth-config-to-app-sync-auth-type-bi-di-mapper.ts index d52094eae50..c1a8dde916a 100644 --- a/packages/amplify-category-api/src/provider-utils/awscloudformation/utils/auth-config-to-app-sync-auth-type-bi-di-mapper.ts +++ b/packages/amplify-category-api/src/provider-utils/awscloudformation/utils/auth-config-to-app-sync-auth-type-bi-di-mapper.ts @@ -30,6 +30,7 @@ const authConfigToAppSyncAuthTypeMap: Record AppSyn API_KEY: authConfig => ({ mode: 'API_KEY', expirationTime: authConfig.apiKeyConfig.apiKeyExpirationDays, + apiKeyExpirationDate: authConfig.apiKeyConfig?.apiKeyExpirationDate, keyDescription: authConfig.apiKeyConfig.description, }), AWS_IAM: () => ({ @@ -54,6 +55,7 @@ const appSyncAuthTypeToAuthConfigMap: Record $TSAny; sharedQuestions: () => $TSAny; showAllHelp: () => $TSAny; + showGlobalSandboxModeWarning: (context: $TSContext) => $TSAny; showHelp: (header: string, commands: { name: string; description: string }[]) => $TSAny; showHelpfulProviderLinks: (context: $TSContext) => $TSAny; showResourceTable: () => $TSAny; @@ -309,9 +310,7 @@ interface AmplifyToolkit { leaveBreadcrumbs: (category: string, resourceName: string, breadcrumbs: unknown) => void; readBreadcrumbs: (category: string, resourceName: string) => $TSAny; loadRuntimePlugin: (context: $TSContext, pluginId: string) => Promise<$TSAny>; - getImportedAuthProperties: ( - context: $TSContext, - ) => { + getImportedAuthProperties: (context: $TSContext) => { imported: boolean; userPoolId?: string; authRoleArn?: string; diff --git a/packages/amplify-cli/src/__tests__/extensions/amplify-helpers/api-key.test.ts b/packages/amplify-cli/src/__tests__/extensions/amplify-helpers/api-key.test.ts new file mode 100644 index 00000000000..afb2d5deb61 --- /dev/null +++ b/packages/amplify-cli/src/__tests__/extensions/amplify-helpers/api-key.test.ts @@ -0,0 +1,78 @@ +import fs from 'fs'; +import { getAppSyncApiConfig, getApiKeyConfig, apiKeyIsActive, hasApiKey } from '../../../extensions/amplify-helpers/api-key'; +import { stateManager } from 'amplify-cli-core'; + +jest.mock('amplify-cli-core', () => { + const original = jest.requireActual('amplify-cli-core'); + const amplifyMeta = fs.readFileSync(`${__dirname}/testData/mockLocalCloud/amplify-meta.json`); + return { + ...original, + stateManager: { + metaFileExists: jest.fn(), + getMeta: jest.fn().mockImplementation(() => JSON.parse(amplifyMeta.toString())), + }, + }; +}); + +const stateManager_mock = stateManager as jest.Mocked; + +describe('getAppSyncApiConfig', () => { + it('returns the api object', async () => { + const result = getAppSyncApiConfig(); + + expect(result).toStrictEqual({ + service: 'AppSync', + providerPlugin: 'awscloudformation', + output: { + authConfig: { + defaultAuthentication: { + authenticationType: 'AWS_IAM', + }, + additionalAuthenticationProviders: [ + { + authenticationType: 'API_KEY', + apiKeyConfig: { + apiKeyExpirationDays: 2, + apiKeyExpirationDate: '2021-08-20T20:38:07.585Z', + description: '', + }, + }, + ], + }, + globalSandboxModeConfig: { + dev: { + enabled: true, + }, + }, + }, + }); + }); +}); + +describe('getApiKeyConfig', () => { + it('returns the api key config', () => { + const result = getApiKeyConfig(); + + expect(result).toStrictEqual({ + apiKeyExpirationDays: 2, + apiKeyExpirationDate: '2021-08-20T20:38:07.585Z', + description: '', + }); + }); +}); + +describe('apiKeyIsActive', () => { + it('returns true if api key is active', () => { + const result = apiKeyIsActive(); + + expect(result).toBe(false); + }); +}); + +describe('hasApiKey', () => { + it('returns true if api key is present', () => { + const result = hasApiKey(); + + expect(result).toBe(true); + }); +}); diff --git a/packages/amplify-cli/src/__tests__/extensions/amplify-helpers/testData/mockLocalCloud/amplify-meta.json b/packages/amplify-cli/src/__tests__/extensions/amplify-helpers/testData/mockLocalCloud/amplify-meta.json new file mode 100644 index 00000000000..aa3b39e78bc --- /dev/null +++ b/packages/amplify-cli/src/__tests__/extensions/amplify-helpers/testData/mockLocalCloud/amplify-meta.json @@ -0,0 +1,30 @@ +{ + "api": { + "ampapp": { + "service": "AppSync", + "providerPlugin": "awscloudformation", + "output": { + "authConfig": { + "defaultAuthentication": { + "authenticationType": "AWS_IAM" + }, + "additionalAuthenticationProviders": [ + { + "authenticationType": "API_KEY", + "apiKeyConfig": { + "apiKeyExpirationDays": 2, + "apiKeyExpirationDate": "2021-08-20T20:38:07.585Z", + "description": "" + } + } + ] + }, + "globalSandboxModeConfig": { + "dev": { + "enabled": true + } + } + } + } + } +} diff --git a/packages/amplify-cli/src/commands/status.ts b/packages/amplify-cli/src/commands/status.ts index 3e11576346a..c821f9c1c94 100644 --- a/packages/amplify-cli/src/commands/status.ts +++ b/packages/amplify-cli/src/commands/status.ts @@ -1,26 +1,28 @@ -import { ViewResourceTableParams, CLIParams, $TSContext } from "amplify-cli-core"; +import { ViewResourceTableParams, CLIParams, $TSContext } from 'amplify-cli-core'; +export const run = async (context: $TSContext) => { + const cliParams: CLIParams = { + cliCommand: context?.input?.command, + cliSubcommands: context?.input?.subCommands, + cliOptions: context?.input?.options, + }; -export const run = async (context : $TSContext) => { - const cliParams:CLIParams = { cliCommand : context?.input?.command, - cliSubcommands: context?.input?.subCommands, - cliOptions : context?.input?.options } - - const view = new ViewResourceTableParams( cliParams ); - if ( context?.input?.subCommands?.includes("help")){ - context.print.info( view.getStyledHelp() ); + const view = new ViewResourceTableParams(cliParams); + if (context?.input?.subCommands?.includes('help')) { + context.print.info(view.getStyledHelp()); } else { try { - await context.amplify.showStatusTable( view ); + await context.amplify.showStatusTable(view); + await context.amplify.showGlobalSandboxModeWarning(context); await context.amplify.showHelpfulProviderLinks(context); await showAmplifyConsoleHostingStatus(context); - } catch ( e ){ + } catch (e) { view.logErrorException(e, context); } } }; -async function showAmplifyConsoleHostingStatus( context) { +async function showAmplifyConsoleHostingStatus(context) { const pluginInfo = context.amplify.getCategoryPluginInfo(context, 'hosting', 'amplifyhosting'); if (pluginInfo && pluginInfo.packageLocation) { const { status } = await import(pluginInfo.packageLocation); diff --git a/packages/amplify-cli/src/domain/amplify-toolkit.ts b/packages/amplify-cli/src/domain/amplify-toolkit.ts index 55f1b41b753..512d7fefd9c 100644 --- a/packages/amplify-cli/src/domain/amplify-toolkit.ts +++ b/packages/amplify-cli/src/domain/amplify-toolkit.ts @@ -38,6 +38,7 @@ export class AmplifyToolkit { private _removeResource: any; private _sharedQuestions: any; private _showAllHelp: any; + private _showGlobalSandboxModeWarning: any; private _showHelp: any; private _showHelpfulProviderLinks: any; private _showResourceTable: any; @@ -240,6 +241,12 @@ export class AmplifyToolkit { this._sharedQuestions = this._sharedQuestions || require(path.join(this._amplifyHelpersDirPath, 'shared-questions')).sharedQuestions; return this._sharedQuestions; } + get showGlobalSandboxModeWarning(): any { + this._showGlobalSandboxModeWarning = + this._showGlobalSandboxModeWarning || + require(path.join(this._amplifyHelpersDirPath, 'show-global-sandbox-mode-warning')).showGlobalSandboxModeWarning; + return this._showGlobalSandboxModeWarning; + } get showHelp(): any { this._showHelp = this._showHelp || require(path.join(this._amplifyHelpersDirPath, 'show-help')).showHelp; return this._showHelp; @@ -261,8 +268,7 @@ export class AmplifyToolkit { } get showStatusTable(): any { - this._showStatusTable = - this._showStatusTable || require(path.join(this._amplifyHelpersDirPath, 'resource-status')).showStatusTable; + this._showStatusTable = this._showStatusTable || require(path.join(this._amplifyHelpersDirPath, 'resource-status')).showStatusTable; return this._showStatusTable; } diff --git a/packages/amplify-cli/src/extensions/amplify-helpers/api-key.ts b/packages/amplify-cli/src/extensions/amplify-helpers/api-key.ts new file mode 100644 index 00000000000..b3f9a1d770e --- /dev/null +++ b/packages/amplify-cli/src/extensions/amplify-helpers/api-key.ts @@ -0,0 +1,51 @@ +import { stateManager } from 'amplify-cli-core'; +import { ApiKeyConfig } from '@aws-amplify/graphql-transformer-core'; + +export function getAppSyncApiConfig(): any { + const apiConfig = stateManager.getMeta()?.api; + let appSyncApi; + + Object.keys(apiConfig).forEach(k => { + if (apiConfig[k]['service'] === 'AppSync') appSyncApi = apiConfig[k]; + }); + + return appSyncApi; +} + +function getDefaultIfApiKey(): ApiKeyConfig | void { + const authConfig = getAppSyncApiConfig()?.output?.authConfig; + const { defaultAuthentication } = authConfig; + + if (defaultAuthentication.authenticationType === 'API_KEY') return defaultAuthentication.apiKeyConfig; +} + +function getAdditionalApiKeyConfig(): ApiKeyConfig | void { + const authConfig = getAppSyncApiConfig()?.output?.authConfig; + const { additionalAuthenticationProviders } = authConfig; + let apiKeyConfig; + + additionalAuthenticationProviders.forEach(authProvider => { + if (authProvider.authenticationType === 'API_KEY') apiKeyConfig = authProvider.apiKeyConfig; + }); + + return apiKeyConfig; +} + +export function getApiKeyConfig(): ApiKeyConfig | void { + return getDefaultIfApiKey() || getAdditionalApiKeyConfig(); +} + +export function apiKeyIsActive(): boolean { + const today = new Date(); + const { apiKeyExpirationDate } = getApiKeyConfig() || {}; + + if (!apiKeyExpirationDate) return false; + + return new Date(apiKeyExpirationDate) > today; +} + +export function hasApiKey(): boolean { + const apiKeyConfig = getApiKeyConfig(); + + return !!apiKeyConfig && !!apiKeyConfig?.apiKeyExpirationDate; +} diff --git a/packages/amplify-cli/src/extensions/amplify-helpers/push-resources.ts b/packages/amplify-cli/src/extensions/amplify-helpers/push-resources.ts index 4e71549cc77..7dd0a64455b 100644 --- a/packages/amplify-cli/src/extensions/amplify-helpers/push-resources.ts +++ b/packages/amplify-cli/src/extensions/amplify-helpers/push-resources.ts @@ -4,6 +4,8 @@ import { onCategoryOutputsChange } from './on-category-outputs-change'; import { initializeEnv } from '../../initialize-env'; import { getProviderPlugins } from './get-provider-plugins'; import { getEnvInfo } from './get-env-info'; +import { globalSandboxModeEnabled, showGlobalSandboxModeWarning } from './show-global-sandbox-mode-warning'; +import { apiKeyIsActive, hasApiKey } from './api-key'; import { EnvironmentDoesNotExistError, exitOnNextTick, stateManager, $TSAny, $TSContext } from 'amplify-cli-core'; export async function pushResources( diff --git a/packages/amplify-cli/src/extensions/amplify-helpers/show-global-sandbox-mode-warning.ts b/packages/amplify-cli/src/extensions/amplify-helpers/show-global-sandbox-mode-warning.ts new file mode 100644 index 00000000000..5456bd062bd --- /dev/null +++ b/packages/amplify-cli/src/extensions/amplify-helpers/show-global-sandbox-mode-warning.ts @@ -0,0 +1,31 @@ +import chalk from 'chalk'; +import { $TSContext } from 'amplify-cli-core'; +import { getAppSyncApiConfig, getApiKeyConfig } from './api-key'; + +export function globalSandboxModeEnabled(context: $TSContext): boolean { + const appSyncApi = getAppSyncApiConfig(); + const currEnvName = context.amplify.getEnvInfo().envName; + const { globalSandboxModeConfig } = appSyncApi.output || {}; + + if (!globalSandboxModeConfig) return false; + + return globalSandboxModeConfig[currEnvName]?.enabled; +} + +export function showGlobalSandboxModeWarning(context: $TSContext): void { + const apiKeyConfig = getApiKeyConfig(); + + if (!apiKeyConfig?.apiKeyExpirationDate) return; + + const expirationDate = new Date(apiKeyConfig.apiKeyExpirationDate); + + if (apiKeyConfig && globalSandboxModeEnabled(context)) { + context.print.info(` +⚠️ WARNING: ${chalk.green('"type AMPLIFY_GLOBAL @allow_public_data_access_with_api_key"')} in your GraphQL schema +allows public create, read, update, and delete access to all models via API Key. This +should only be used for testing purposes. API Key expiration date is: ${expirationDate.toLocaleDateString()} + +To configure PRODUCTION-READY authorization rules, review: https://docs.amplify.aws/cli/graphql-transformer/auth +`); + } +} diff --git a/packages/amplify-graphql-transformer-core/src/transformation/transform.ts b/packages/amplify-graphql-transformer-core/src/transformation/transform.ts index 2f871c98e5f..c1314a50eb9 100644 --- a/packages/amplify-graphql-transformer-core/src/transformation/transform.ts +++ b/packages/amplify-graphql-transformer-core/src/transformation/transform.ts @@ -1,7 +1,12 @@ /* eslint-disable no-new */ -import { FeatureFlagProvider, GraphQLAPIProvider, TransformerPluginProvider, TransformHostProvider } from '@aws-amplify/graphql-transformer-interfaces'; +import { + FeatureFlagProvider, + GraphQLAPIProvider, + TransformerPluginProvider, + TransformHostProvider, +} from '@aws-amplify/graphql-transformer-interfaces'; import { AuthorizationMode, AuthorizationType } from '@aws-cdk/aws-appsync'; -import { App, Aws, CfnOutput, Fn } from '@aws-cdk/core'; +import { App, Aws, CfnOutput, Fn, Duration, Expiration } from '@aws-cdk/core'; import assert from 'assert'; import { EnumTypeDefinitionNode, @@ -83,12 +88,14 @@ export class GraphQLTransform { } const sortedTransformers = sortTransformerPlugins(options.transformers); this.transformers = sortedTransformers; + const apiKeyExpirationDate = Expiration.after(Duration.days(7)).date; this.authConfig = options.authConfig || { defaultAuthentication: { authenticationType: 'API_KEY', apiKeyConfig: { apiKeyExpirationDays: 7, + apiKeyExpirationDate, description: 'Default API Key', }, }, @@ -252,7 +259,7 @@ export class GraphQLTransform { const api = new GraphQLApi(rootStack, 'GraphQLAPI', { name: `${apiName}-${envName.valueAsString}`, authorizationConfig, - host: this.options.host + host: this.options.host, }); const authModes = [authorizationConfig.defaultAuthorization, ...(authorizationConfig.additionalAuthorizationModes || [])].map( mode => mode?.authorizationType, diff --git a/packages/amplify-graphql-transformer-core/src/transformation/transformer-config.ts b/packages/amplify-graphql-transformer-core/src/transformation/transformer-config.ts index 1676436e1e5..3be94d1faa8 100644 --- a/packages/amplify-graphql-transformer-core/src/transformation/transformer-config.ts +++ b/packages/amplify-graphql-transformer-core/src/transformation/transformer-config.ts @@ -11,7 +11,11 @@ export type AppSyncAuthConfiguration = { additionalAuthenticationProviders: Array; }; -export type AppSyncAuthConfigurationEntry = AppSyncAuthConfigurationUserPoolEntry | AppSyncAuthConfigurationAPIKeyEntry | AppSyncAuthConfigurationIAMEntry | AppSyncAuthConfigurationOIDCEntry; +export type AppSyncAuthConfigurationEntry = + | AppSyncAuthConfigurationUserPoolEntry + | AppSyncAuthConfigurationAPIKeyEntry + | AppSyncAuthConfigurationIAMEntry + | AppSyncAuthConfigurationOIDCEntry; export type AppSyncAuthConfigurationAPIKeyEntry = { authenticationType: 'API_KEY'; apiKeyConfig: ApiKeyConfig; @@ -32,6 +36,7 @@ export type AppSyncAuthConfigurationOIDCEntry = { export type ApiKeyConfig = { description?: string; apiKeyExpirationDays: number; + apiKeyExpirationDate?: Date; }; export type UserPoolConfig = { userPoolId: string; diff --git a/packages/amplify-headless-interface/src/interface/api/add.ts b/packages/amplify-headless-interface/src/interface/api/add.ts index 51f44124538..081eaf07e57 100644 --- a/packages/amplify-headless-interface/src/interface/api/add.ts +++ b/packages/amplify-headless-interface/src/interface/api/add.ts @@ -130,6 +130,7 @@ export type AppSyncAuthType = export interface AppSyncAPIKeyAuthType { mode: 'API_KEY'; expirationTime?: number; + apiKeyExpirationDate?: Date; keyDescription?: string; } diff --git a/packages/graphql-auth-transformer/src/ModelAuthTransformer.ts b/packages/graphql-auth-transformer/src/ModelAuthTransformer.ts index cf2fab44ac3..6e41670abd6 100644 --- a/packages/graphql-auth-transformer/src/ModelAuthTransformer.ts +++ b/packages/graphql-auth-transformer/src/ModelAuthTransformer.ts @@ -98,6 +98,7 @@ export type AppSyncAuthConfigurationEntry = { export type ApiKeyConfig = { description?: string; apiKeyExpirationDays: number; + apiKeyExpirationDate?: Date; }; export type UserPoolConfig = { userPoolId: string; @@ -1387,9 +1388,8 @@ operations will be generated by the CLI.`, // In create mutations, the dynamic group and ownership authorization checks // are done before calling PutItem. - const dynamicGroupAuthorizationExpression = this.resources.dynamicGroupAuthorizationExpressionForCreateOperations( - dynamicGroupAuthorizationRules, - ); + const dynamicGroupAuthorizationExpression = + this.resources.dynamicGroupAuthorizationExpressionForCreateOperations(dynamicGroupAuthorizationRules); const fieldIsList = (fieldName: string) => { const field = parent.fields.find(field => field.name.value === fieldName); if (field) { @@ -1547,9 +1547,8 @@ operations will be generated by the CLI.`, ]), ); - const throwIfNotStaticGroupAuthorizedOrAuthConditionIsEmpty = this.resources.throwIfNotStaticGroupAuthorizedOrAuthConditionIsEmpty( - field, - ); + const throwIfNotStaticGroupAuthorizedOrAuthConditionIsEmpty = + this.resources.throwIfNotStaticGroupAuthorizedOrAuthConditionIsEmpty(field); // If we've any modes to check, then add the authMode check code block // to the start of the resolver. From 694e0910f151e7e2d716344ba0c128ebb1880c9b Mon Sep 17 00:00:00 2001 From: Danielle Adams Date: Fri, 27 Aug 2021 18:39:53 -0400 Subject: [PATCH 3/9] feat(amplify-category-api): prompt api key create when invalid with sandbox mode --- .../cfn-api-artifact-handler.test.ts | 61 +++++++++++++++++++ .../appSync-walkthrough.test.ts | 2 +- packages/amplify-category-api/src/index.ts | 1 + .../provider-utils/api-artifact-handler.ts | 1 + .../appSync-walkthrough.ts | 2 +- .../service-walkthrough-to-add-api-key.ts | 25 ++++++++ .../amplify-helpers/push-resources.ts | 6 ++ 7 files changed, 96 insertions(+), 2 deletions(-) create mode 100644 packages/amplify-category-api/src/provider-utils/awscloudformation/utils/service-walkthrough-to-add-api-key.ts diff --git a/packages/amplify-category-api/src/__tests__/provider-utils/awscloudformation/cfn-api-artifact-handler.test.ts b/packages/amplify-category-api/src/__tests__/provider-utils/awscloudformation/cfn-api-artifact-handler.test.ts index 28e2aec71d3..05ed4a3afe1 100644 --- a/packages/amplify-category-api/src/__tests__/provider-utils/awscloudformation/cfn-api-artifact-handler.test.ts +++ b/packages/amplify-category-api/src/__tests__/provider-utils/awscloudformation/cfn-api-artifact-handler.test.ts @@ -245,3 +245,64 @@ describe('update artifacts', () => { expect(context_stub.print.warning.mock.calls.length).toBe(3); }); }); + +describe('update artifacts without graphql compile', () => { + let cfnApiArtifactHandler: ApiArtifactHandler; + let updateRequestStub: UpdateApiRequest; + const updateRequestStubBase: UpdateApiRequest = { + version: 1, + serviceModification: { + serviceName: 'AppSync', + }, + }; + + beforeAll(() => { + getAppSyncResourceName_mock.mockImplementation(() => testApiName); + getAppSyncAuthConfig_mock.mockImplementation(() => ({ + defaultAuthentication: { + authenticationType: 'AMAZON_COGNITO_USER_POOLS', + userPoolConfig: { + userPoolId: 'myUserPoolId', + }, + }, + additionalAuthenticationProviders: [], + })); + }); + + beforeEach(() => { + jest.clearAllMocks(); + updateRequestStub = _.cloneDeep(updateRequestStubBase); + cfnApiArtifactHandler = getCfnApiArtifactHandler(context_stub); + }); + + it('throws error if no GQL API in project', () => { + getAppSyncResourceName_mock.mockImplementationOnce(() => undefined); + return expect(cfnApiArtifactHandler.updateArtifactsWithoutCompile(updateRequestStub)).rejects.toMatchInlineSnapshot( + `[Error: No AppSync API configured in the project. Use 'amplify add api' to create an API.]`, + ); + }); + + it('writes new schema if specified', async () => { + const newSchemaContents = 'a new schema'; + updateRequestStub.serviceModification.transformSchema = newSchemaContents; + await cfnApiArtifactHandler.updateArtifactsWithoutCompile(updateRequestStub); + expect(fs_mock.writeFileSync.mock.calls.length).toBe(1); + expect(fs_mock.writeFileSync.mock.calls[0][1]).toBe(newSchemaContents); + }); + + it('updates resolver config if not empty', async () => { + updateRequestStub.serviceModification.conflictResolution = { + defaultResolutionStrategy: { + type: 'OPTIMISTIC_CONCURRENCY', + }, + }; + await cfnApiArtifactHandler.updateArtifactsWithoutCompile(updateRequestStub); + expect(writeTransformerConfiguration_mock.mock.calls.length).toBe(1); + }); + + it('updates meta files after update', async () => { + await cfnApiArtifactHandler.updateArtifactsWithoutCompile(updateRequestStub); + expect(context_stub.amplify.updateamplifyMetaAfterResourceUpdate.mock.calls.length).toBe(1); + expect(context_stub.amplify.updateBackendConfigAfterResourceUpdate.mock.calls.length).toBe(1); + }); +}); diff --git a/packages/amplify-category-api/src/__tests__/provider-utils/awscloudformation/service-walkthroughs/appSync-walkthrough.test.ts b/packages/amplify-category-api/src/__tests__/provider-utils/awscloudformation/service-walkthroughs/appSync-walkthrough.test.ts index a664b0b4698..1d7ed55cdfd 100644 --- a/packages/amplify-category-api/src/__tests__/provider-utils/awscloudformation/service-walkthroughs/appSync-walkthrough.test.ts +++ b/packages/amplify-category-api/src/__tests__/provider-utils/awscloudformation/service-walkthroughs/appSync-walkthrough.test.ts @@ -3,7 +3,7 @@ import { askAdditionalAuthQuestions, } from '../../../../provider-utils/awscloudformation/service-walkthroughs/appSync-walkthrough'; import { authConfigHasApiKey, getAppSyncAuthConfig } from '../../../../provider-utils/awscloudformation/utils/amplify-meta-utils'; -import { FeatureFlags, CLIEnvironmentProvider, FeatureFlagRegistration } from 'amplify-cli-core'; +import { FeatureFlags } from 'amplify-cli-core'; jest.mock('../../../../provider-utils/awscloudformation/utils/amplify-meta-utils', () => ({ getAppSyncAuthConfig: jest.fn(), authConfigHasApiKey: jest.fn(), diff --git a/packages/amplify-category-api/src/index.ts b/packages/amplify-category-api/src/index.ts index af7f1625011..e14947c1021 100644 --- a/packages/amplify-category-api/src/index.ts +++ b/packages/amplify-category-api/src/index.ts @@ -15,6 +15,7 @@ export { processDockerConfig, } from './provider-utils/awscloudformation/utils/containers-artifacts'; export { getContainers } from './provider-utils/awscloudformation/docker-compose'; +export { promptToAddApiKey } from './provider-utils/awscloudformation/utils/service-walkthrough-to-add-api-key'; const category = 'api'; diff --git a/packages/amplify-category-api/src/provider-utils/api-artifact-handler.ts b/packages/amplify-category-api/src/provider-utils/api-artifact-handler.ts index a3b7de27c51..a261ae2f705 100644 --- a/packages/amplify-category-api/src/provider-utils/api-artifact-handler.ts +++ b/packages/amplify-category-api/src/provider-utils/api-artifact-handler.ts @@ -3,4 +3,5 @@ import { AddApiRequest, UpdateApiRequest } from 'amplify-headless-interface'; export interface ApiArtifactHandler { createArtifacts(request: AddApiRequest): Promise; updateArtifacts(request: UpdateApiRequest): Promise; + updateArtifactsWithoutCompile(request: UpdateApiRequest): Promise; } diff --git a/packages/amplify-category-api/src/provider-utils/awscloudformation/service-walkthroughs/appSync-walkthrough.ts b/packages/amplify-category-api/src/provider-utils/awscloudformation/service-walkthroughs/appSync-walkthrough.ts index 6d5f87e36f8..303f94151c4 100644 --- a/packages/amplify-category-api/src/provider-utils/awscloudformation/service-walkthroughs/appSync-walkthrough.ts +++ b/packages/amplify-category-api/src/provider-utils/awscloudformation/service-walkthroughs/appSync-walkthrough.ts @@ -605,7 +605,7 @@ async function askUserPoolQuestions(context) { }; } -async function askApiKeyQuestions() { +export async function askApiKeyQuestions() { const apiKeyQuestions = [ { type: 'input', diff --git a/packages/amplify-category-api/src/provider-utils/awscloudformation/utils/service-walkthrough-to-add-api-key.ts b/packages/amplify-category-api/src/provider-utils/awscloudformation/utils/service-walkthrough-to-add-api-key.ts new file mode 100644 index 00000000000..968e7e27f75 --- /dev/null +++ b/packages/amplify-category-api/src/provider-utils/awscloudformation/utils/service-walkthrough-to-add-api-key.ts @@ -0,0 +1,25 @@ +import chalk from 'chalk'; +import { askApiKeyQuestions } from '../service-walkthroughs/appSync-walkthrough'; +import { authConfigToAppSyncAuthType } from '../utils/auth-config-to-app-sync-auth-type-bi-di-mapper'; +import { getCfnApiArtifactHandler } from '../cfn-api-artifact-handler'; + +export async function promptToAddApiKey(context): Promise { + context.print.info(` +⚠️ WARNING: Global Sandbox Mode has been enabled, which requires a valid API key. If +you'd like to disable, remove ${chalk.green('"type AMPLIFY_GLOBAL @allow_public_data_access_with_api_key"')} +from your GraphQL schema and run 'amplify push' again. If you'd like to proceed with +sandbox mode disabled in '${context.amplify.getEnvInfo().envName}', do not create an API Key. +`); + if (await context.prompt.confirm('Would you like to create an API Key?', true)) { + const apiKeyConfig = await askApiKeyQuestions(); + const authConfig = [apiKeyConfig]; + + getCfnApiArtifactHandler(context).updateArtifactsWithoutCompile({ + version: 1, + serviceModification: { + serviceName: 'AppSync', + additionalAuthTypes: authConfig.map(authConfigToAppSyncAuthType), + }, + }); + } +} diff --git a/packages/amplify-cli/src/extensions/amplify-helpers/push-resources.ts b/packages/amplify-cli/src/extensions/amplify-helpers/push-resources.ts index 7dd0a64455b..a06e5d50f95 100644 --- a/packages/amplify-cli/src/extensions/amplify-helpers/push-resources.ts +++ b/packages/amplify-cli/src/extensions/amplify-helpers/push-resources.ts @@ -7,6 +7,7 @@ import { getEnvInfo } from './get-env-info'; import { globalSandboxModeEnabled, showGlobalSandboxModeWarning } from './show-global-sandbox-mode-warning'; import { apiKeyIsActive, hasApiKey } from './api-key'; import { EnvironmentDoesNotExistError, exitOnNextTick, stateManager, $TSAny, $TSContext } from 'amplify-cli-core'; +import { promptToAddApiKey } from 'amplify-category-api'; export async function pushResources( context: $TSContext, @@ -69,6 +70,11 @@ export async function pushResources( continueToPush = await context.amplify.confirmPrompt('Are you sure you want to continue?'); } + if (globalSandboxModeEnabled(context)) { + if (!apiKeyIsActive() || !hasApiKey()) await promptToAddApiKey(context); + else showGlobalSandboxModeWarning(context); + } + if (continueToPush) { try { // Get current-cloud-backend's amplify-meta From ea9ea39a9fd3bc1673dd1cdb6c142f188b6164da Mon Sep 17 00:00:00 2001 From: Danielle Adams Date: Fri, 27 Aug 2021 18:41:36 -0400 Subject: [PATCH 4/9] feat(graphql-model-transformer): set up transformer for sandbox mode directive --- ...ify-graphql-index-transformer.test.ts.snap | 43 ++++++++++++++ ...aphql-primary-key-transformer.test.ts.snap | 40 +++++++++++++ .../model-transformer.test.ts.snap | 9 +++ .../src/__tests__/model-transformer.test.ts | 21 +++++++ .../src/graphql-model-transformer.ts | 13 +++-- .../src/resolvers/common.ts | 13 ++++- .../src/resolvers/mutation.ts | 13 +++-- .../src/resolvers/query.ts | 7 ++- ...-graphql-has-many-transformer.test.ts.snap | 58 +++++++++++++++++++ ...aphql-searchable-transformer.tests.ts.snap | 5 ++ .../package.json | 1 + .../src/graphql-api.ts | 29 ++++++++-- yarn.lock | 22 +++++++ 13 files changed, 258 insertions(+), 16 deletions(-) diff --git a/packages/amplify-graphql-index-transformer/src/__tests__/__snapshots__/amplify-graphql-index-transformer.test.ts.snap b/packages/amplify-graphql-index-transformer/src/__tests__/__snapshots__/amplify-graphql-index-transformer.test.ts.snap index b7414b70b56..6a40bd906c5 100644 --- a/packages/amplify-graphql-index-transformer/src/__tests__/__snapshots__/amplify-graphql-index-transformer.test.ts.snap +++ b/packages/amplify-graphql-index-transformer/src/__tests__/__snapshots__/amplify-graphql-index-transformer.test.ts.snap @@ -66,6 +66,7 @@ $util.qr($mergedValues.putAll($util.defaultIfNull($ctx.args.input, {}))) $util.qr($mergedValues.putAll($util.defaultIfNull($ctx.args.input, {}))) ## set the typename ** $util.qr($mergedValues.put(\\"__typename\\", \\"Test\\")) +$util.unauthorized() #set( $PutObject = { \\"version\\": \\"2018-05-29\\", \\"operation\\": \\"PutItem\\", @@ -149,6 +150,7 @@ $util.qr($ctx.args.input.put(\\"kind#date\\",\\"\${mergedValues.kind}#\${mergedV \\"version\\": \\"2018-05-29\\", \\"operation\\": \\"DeleteItem\\" } ) +$util.unauthorized() #if( $ctx.stash.metadata.modelObjectKey ) #set( $Key = $ctx.stash.metadata.modelObjectKey ) #else @@ -256,6 +258,7 @@ $util.qr($mergedValues.putAll($util.defaultIfNull($ctx.args.input, {}))) #set( $expSet = {} ) #set( $expAdd = {} ) #set( $expRemove = [] ) +$util.unauthorized() #if( $ctx.stash.metadata.modelObjectKey ) #set( $Key = $ctx.stash.metadata.modelObjectKey ) #else @@ -385,6 +388,7 @@ $util.toJson($UpdateItem) \\"version\\": \\"2018-05-29\\", \\"operation\\": \\"GetItem\\" } ) +$util.unauthorized() #if( $ctx.stash.metadata.modelObjectKey ) #set( $key = $ctx.stash.metadata.modelObjectKey ) #else @@ -532,6 +536,7 @@ $util.toJson($ctx.result)", \\"version\\": \\"2018-05-29\\", \\"limit\\": $limit } ) +$util.unauthorized() #if( $context.args.nextToken ) #set( $ListRequest.nextToken = $context.args.nextToken ) #end @@ -714,6 +719,7 @@ $util.qr($mergedValues.putAll($util.defaultIfNull($ctx.args.input, {}))) $util.qr($mergedValues.putAll($util.defaultIfNull($ctx.args.input, {}))) ## set the typename ** $util.qr($mergedValues.put(\\"__typename\\", \\"Test\\")) +$util.unauthorized() #set( $PutObject = { \\"version\\": \\"2018-05-29\\", \\"operation\\": \\"PutItem\\", @@ -797,6 +803,7 @@ $util.qr($ctx.args.input.put(\\"kind#date\\",\\"\${mergedValues.kind}#\${mergedV \\"version\\": \\"2018-05-29\\", \\"operation\\": \\"DeleteItem\\" } ) +$util.unauthorized() #if( $ctx.stash.metadata.modelObjectKey ) #set( $Key = $ctx.stash.metadata.modelObjectKey ) #else @@ -904,6 +911,7 @@ $util.qr($mergedValues.putAll($util.defaultIfNull($ctx.args.input, {}))) #set( $expSet = {} ) #set( $expAdd = {} ) #set( $expRemove = [] ) +$util.unauthorized() #if( $ctx.stash.metadata.modelObjectKey ) #set( $Key = $ctx.stash.metadata.modelObjectKey ) #else @@ -1033,6 +1041,7 @@ $util.toJson($UpdateItem) \\"version\\": \\"2018-05-29\\", \\"operation\\": \\"GetItem\\" } ) +$util.unauthorized() #if( $ctx.stash.metadata.modelObjectKey ) #set( $key = $ctx.stash.metadata.modelObjectKey ) #else @@ -1180,6 +1189,7 @@ $util.toJson($ctx.result)", \\"version\\": \\"2018-05-29\\", \\"limit\\": $limit } ) +$util.unauthorized() #if( $context.args.nextToken ) #set( $ListRequest.nextToken = $context.args.nextToken ) #end @@ -1284,6 +1294,7 @@ $util.qr($mergedValues.putAll($util.defaultIfNull($ctx.args.input, {}))) $util.qr($mergedValues.putAll($util.defaultIfNull($ctx.args.input, {}))) ## set the typename ** $util.qr($mergedValues.put(\\"__typename\\", \\"Test\\")) +$util.unauthorized() #set( $PutObject = { \\"version\\": \\"2018-05-29\\", \\"operation\\": \\"PutItem\\", @@ -1367,6 +1378,7 @@ $util.qr($ctx.args.input.put(\\"kind#date\\",\\"\${mergedValues.kind}#\${mergedV \\"version\\": \\"2018-05-29\\", \\"operation\\": \\"DeleteItem\\" } ) +$util.unauthorized() #if( $ctx.stash.metadata.modelObjectKey ) #set( $Key = $ctx.stash.metadata.modelObjectKey ) #else @@ -1474,6 +1486,7 @@ $util.qr($mergedValues.putAll($util.defaultIfNull($ctx.args.input, {}))) #set( $expSet = {} ) #set( $expAdd = {} ) #set( $expRemove = [] ) +$util.unauthorized() #if( $ctx.stash.metadata.modelObjectKey ) #set( $Key = $ctx.stash.metadata.modelObjectKey ) #else @@ -1603,6 +1616,7 @@ $util.toJson($UpdateItem) \\"version\\": \\"2018-05-29\\", \\"operation\\": \\"GetItem\\" } ) +$util.unauthorized() #if( $ctx.stash.metadata.modelObjectKey ) #set( $key = $ctx.stash.metadata.modelObjectKey ) #else @@ -1750,6 +1764,7 @@ $util.toJson($ctx.result)", \\"version\\": \\"2018-05-29\\", \\"limit\\": $limit } ) +$util.unauthorized() #if( $context.args.nextToken ) #set( $ListRequest.nextToken = $context.args.nextToken ) #end @@ -1931,6 +1946,7 @@ exports[`GSI composite sort keys are wrapped in conditional to check presence in $util.qr($mergedValues.putAll($util.defaultIfNull($ctx.args.input, {}))) ## set the typename ** $util.qr($mergedValues.put(\\"__typename\\", \\"Person\\")) +$util.unauthorized() #set( $PutObject = { \\"version\\": \\"2018-05-29\\", \\"operation\\": \\"PutItem\\", @@ -2004,6 +2020,7 @@ $util.qr($mergedValues.putAll($util.defaultIfNull($ctx.args.input, {}))) #set( $expSet = {} ) #set( $expAdd = {} ) #set( $expRemove = [] ) +$util.unauthorized() #if( $ctx.stash.metadata.modelObjectKey ) #set( $Key = $ctx.stash.metadata.modelObjectKey ) #else @@ -2174,6 +2191,7 @@ $util.qr($ctx.stash.metadata.put(\\"modelObjectKey\\", { $util.qr($mergedValues.putAll($util.defaultIfNull($ctx.args.input, {}))) ## set the typename ** $util.qr($mergedValues.put(\\"__typename\\", \\"Test\\")) +$util.unauthorized() #set( $PutObject = { \\"version\\": \\"2018-05-29\\", \\"operation\\": \\"PutItem\\", @@ -2255,6 +2273,7 @@ $util.qr($ctx.stash.metadata.put(\\"modelObjectKey\\", { \\"version\\": \\"2018-05-29\\", \\"operation\\": \\"DeleteItem\\" } ) +$util.unauthorized() #if( $ctx.stash.metadata.modelObjectKey ) #set( $Key = $ctx.stash.metadata.modelObjectKey ) #else @@ -2347,6 +2366,7 @@ $util.qr($mergedValues.putAll($util.defaultIfNull($ctx.args.input, {}))) #set( $expSet = {} ) #set( $expAdd = {} ) #set( $expRemove = [] ) +$util.unauthorized() #if( $ctx.stash.metadata.modelObjectKey ) #set( $Key = $ctx.stash.metadata.modelObjectKey ) #else @@ -2483,6 +2503,7 @@ $util.qr($ctx.stash.metadata.put(\\"modelObjectKey\\", { \\"version\\": \\"2018-05-29\\", \\"operation\\": \\"GetItem\\" } ) +$util.unauthorized() #if( $ctx.stash.metadata.modelObjectKey ) #set( $key = $ctx.stash.metadata.modelObjectKey ) #else @@ -2692,6 +2713,7 @@ $util.qr($ctx.stash.put(\\"modelQueryExpression\\", $modelQueryExpression)) \\"version\\": \\"2018-05-29\\", \\"limit\\": $limit } ) +$util.unauthorized() #if( $context.args.nextToken ) #set( $ListRequest.nextToken = $context.args.nextToken ) #end @@ -2912,6 +2934,7 @@ $util.qr($mergedValues.putAll($util.defaultIfNull($ctx.args.input, {}))) $util.qr($mergedValues.putAll($util.defaultIfNull($ctx.args.input, {}))) ## set the typename ** $util.qr($mergedValues.put(\\"__typename\\", \\"ContentCategory\\")) +$util.unauthorized() #set( $PutObject = { \\"version\\": \\"2018-05-29\\", \\"operation\\": \\"PutItem\\", @@ -3014,6 +3037,7 @@ $util.toJson({ $util.qr($mergedValues.putAll($util.defaultIfNull($ctx.args.input, {}))) ## set the typename ** $util.qr($mergedValues.put(\\"__typename\\", \\"Blog\\")) +$util.unauthorized() #set( $PutObject = { \\"version\\": \\"2018-05-29\\", \\"operation\\": \\"PutItem\\", @@ -3135,6 +3159,7 @@ $util.qr($ctx.args.input.put(\\"status#createdAt\\",\\"\${mergedValues.status}#\ $util.qr($mergedValues.putAll($util.defaultIfNull($ctx.args.input, {}))) ## set the typename ** $util.qr($mergedValues.put(\\"__typename\\", \\"Item\\")) +$util.unauthorized() #set( $PutObject = { \\"version\\": \\"2018-05-29\\", \\"operation\\": \\"PutItem\\", @@ -3249,6 +3274,7 @@ $util.qr($ctx.stash.metadata.put(\\"modelObjectKey\\", { $util.qr($mergedValues.putAll($util.defaultIfNull($ctx.args.input, {}))) ## set the typename ** $util.qr($mergedValues.put(\\"__typename\\", \\"Test\\")) +$util.unauthorized() #set( $PutObject = { \\"version\\": \\"2018-05-29\\", \\"operation\\": \\"PutItem\\", @@ -3351,6 +3377,7 @@ $util.toJson({ $util.qr($mergedValues.putAll($util.defaultIfNull($ctx.args.input, {}))) ## set the typename ** $util.qr($mergedValues.put(\\"__typename\\", \\"Todo\\")) +$util.unauthorized() #set( $PutObject = { \\"version\\": \\"2018-05-29\\", \\"operation\\": \\"PutItem\\", @@ -3421,6 +3448,7 @@ $util.toJson($PutObject) \\"version\\": \\"2018-05-29\\", \\"operation\\": \\"DeleteItem\\" } ) +$util.unauthorized() #if( $ctx.stash.metadata.modelObjectKey ) #set( $Key = $ctx.stash.metadata.modelObjectKey ) #else @@ -3498,6 +3526,7 @@ $util.qr($ctx.args.input.put(\\"type#language#datetime\\",\\"\${mergedValues.typ \\"version\\": \\"2018-05-29\\", \\"operation\\": \\"DeleteItem\\" } ) +$util.unauthorized() #if( $ctx.stash.metadata.modelObjectKey ) #set( $Key = $ctx.stash.metadata.modelObjectKey ) #else @@ -3573,6 +3602,7 @@ $util.qr($ctx.stash.metadata.put(\\"modelObjectKey\\", { \\"version\\": \\"2018-05-29\\", \\"operation\\": \\"DeleteItem\\" } ) +$util.unauthorized() #if( $ctx.stash.metadata.modelObjectKey ) #set( $Key = $ctx.stash.metadata.modelObjectKey ) #else @@ -3648,6 +3678,7 @@ $util.qr($ctx.stash.metadata.put(\\"modelObjectKey\\", { \\"version\\": \\"2018-05-29\\", \\"operation\\": \\"DeleteItem\\" } ) +$util.unauthorized() #if( $ctx.stash.metadata.modelObjectKey ) #set( $Key = $ctx.stash.metadata.modelObjectKey ) #else @@ -3712,6 +3743,7 @@ $util.toJson($DeleteRequest) \\"version\\": \\"2018-05-29\\", \\"operation\\": \\"DeleteItem\\" } ) +$util.unauthorized() #if( $ctx.stash.metadata.modelObjectKey ) #set( $Key = $ctx.stash.metadata.modelObjectKey ) #else @@ -3792,6 +3824,7 @@ $util.qr($mergedValues.putAll($util.defaultIfNull($ctx.args.input, {}))) #set( $expSet = {} ) #set( $expAdd = {} ) #set( $expRemove = [] ) +$util.unauthorized() #if( $ctx.stash.metadata.modelObjectKey ) #set( $Key = $ctx.stash.metadata.modelObjectKey ) #else @@ -3956,6 +3989,7 @@ $util.qr($mergedValues.putAll($util.defaultIfNull($ctx.args.input, {}))) #set( $expSet = {} ) #set( $expAdd = {} ) #set( $expRemove = [] ) +$util.unauthorized() #if( $ctx.stash.metadata.modelObjectKey ) #set( $Key = $ctx.stash.metadata.modelObjectKey ) #else @@ -4113,6 +4147,7 @@ $util.qr($mergedValues.putAll($util.defaultIfNull($ctx.args.input, {}))) #set( $expSet = {} ) #set( $expAdd = {} ) #set( $expRemove = [] ) +$util.unauthorized() #if( $ctx.stash.metadata.modelObjectKey ) #set( $Key = $ctx.stash.metadata.modelObjectKey ) #else @@ -4258,6 +4293,7 @@ $util.qr($mergedValues.putAll($util.defaultIfNull($ctx.args.input, {}))) #set( $expSet = {} ) #set( $expAdd = {} ) #set( $expRemove = [] ) +$util.unauthorized() #if( $ctx.stash.metadata.modelObjectKey ) #set( $Key = $ctx.stash.metadata.modelObjectKey ) #else @@ -4425,6 +4461,7 @@ $util.toJson($ctx.result)", \\"version\\": \\"2018-05-29\\", \\"operation\\": \\"GetItem\\" } ) +$util.unauthorized() #if( $ctx.stash.metadata.modelObjectKey ) #set( $key = $ctx.stash.metadata.modelObjectKey ) #else @@ -4454,6 +4491,7 @@ $util.qr($ctx.stash.metadata.put(\\"modelObjectKey\\", { \\"version\\": \\"2018-05-29\\", \\"operation\\": \\"GetItem\\" } ) +$util.unauthorized() #if( $ctx.stash.metadata.modelObjectKey ) #set( $key = $ctx.stash.metadata.modelObjectKey ) #else @@ -4483,6 +4521,7 @@ $util.qr($ctx.stash.metadata.put(\\"modelObjectKey\\", { \\"version\\": \\"2018-05-29\\", \\"operation\\": \\"GetItem\\" } ) +$util.unauthorized() #if( $ctx.stash.metadata.modelObjectKey ) #set( $key = $ctx.stash.metadata.modelObjectKey ) #else @@ -4505,6 +4544,7 @@ $util.toJson($GetRequest) \\"version\\": \\"2018-05-29\\", \\"operation\\": \\"GetItem\\" } ) +$util.unauthorized() #if( $ctx.stash.metadata.modelObjectKey ) #set( $key = $ctx.stash.metadata.modelObjectKey ) #else @@ -4684,6 +4724,7 @@ $util.toJson($ctx.result)", \\"version\\": \\"2018-05-29\\", \\"limit\\": $limit } ) +$util.unauthorized() #if( $context.args.nextToken ) #set( $ListRequest.nextToken = $context.args.nextToken ) #end @@ -5098,6 +5139,7 @@ $util.qr($ctx.stash.put(\\"modelQueryExpression\\", $modelQueryExpression)) \\"version\\": \\"2018-05-29\\", \\"limit\\": $limit } ) +$util.unauthorized() #if( $context.args.nextToken ) #set( $ListRequest.nextToken = $context.args.nextToken ) #end @@ -5201,6 +5243,7 @@ $util.qr($ctx.stash.put(\\"modelQueryExpression\\", $modelQueryExpression)) \\"version\\": \\"2018-05-29\\", \\"limit\\": $limit } ) +$util.unauthorized() #if( $context.args.nextToken ) #set( $ListRequest.nextToken = $context.args.nextToken ) #end diff --git a/packages/amplify-graphql-index-transformer/src/__tests__/__snapshots__/amplify-graphql-primary-key-transformer.test.ts.snap b/packages/amplify-graphql-index-transformer/src/__tests__/__snapshots__/amplify-graphql-primary-key-transformer.test.ts.snap index 327c5ae5eca..cd86d82e6bb 100644 --- a/packages/amplify-graphql-index-transformer/src/__tests__/__snapshots__/amplify-graphql-primary-key-transformer.test.ts.snap +++ b/packages/amplify-graphql-index-transformer/src/__tests__/__snapshots__/amplify-graphql-primary-key-transformer.test.ts.snap @@ -58,6 +58,7 @@ $util.qr($ctx.args.input.put(\\"kind#other\\",\\"\${mergedValues.kind}#\${merged $util.qr($mergedValues.putAll($util.defaultIfNull($ctx.args.input, {}))) ## set the typename ** $util.qr($mergedValues.put(\\"__typename\\", \\"Test\\")) +$util.unauthorized() #set( $PutObject = { \\"version\\": \\"2018-05-29\\", \\"operation\\": \\"PutItem\\", @@ -139,6 +140,7 @@ $util.qr($ctx.stash.metadata.put(\\"modelObjectKey\\", { \\"version\\": \\"2018-05-29\\", \\"operation\\": \\"DeleteItem\\" } ) +$util.unauthorized() #if( $ctx.stash.metadata.modelObjectKey ) #set( $Key = $ctx.stash.metadata.modelObjectKey ) #else @@ -238,6 +240,7 @@ $util.qr($mergedValues.putAll($util.defaultIfNull($ctx.args.input, {}))) #set( $expSet = {} ) #set( $expAdd = {} ) #set( $expRemove = [] ) +$util.unauthorized() #if( $ctx.stash.metadata.modelObjectKey ) #set( $Key = $ctx.stash.metadata.modelObjectKey ) #else @@ -374,6 +377,7 @@ $util.qr($ctx.stash.metadata.put(\\"modelObjectKey\\", { \\"version\\": \\"2018-05-29\\", \\"operation\\": \\"GetItem\\" } ) +$util.unauthorized() #if( $ctx.stash.metadata.modelObjectKey ) #set( $key = $ctx.stash.metadata.modelObjectKey ) #else @@ -505,6 +509,7 @@ $util.qr($ctx.stash.put(\\"modelQueryExpression\\", $modelQueryExpression)) \\"version\\": \\"2018-05-29\\", \\"limit\\": $limit } ) +$util.unauthorized() #if( $context.args.nextToken ) #set( $ListRequest.nextToken = $context.args.nextToken ) #end @@ -594,6 +599,7 @@ $util.qr($ctx.stash.metadata.put(\\"modelObjectKey\\", { $util.qr($mergedValues.putAll($util.defaultIfNull($ctx.args.input, {}))) ## set the typename ** $util.qr($mergedValues.put(\\"__typename\\", \\"Test\\")) +$util.unauthorized() #set( $PutObject = { \\"version\\": \\"2018-05-29\\", \\"operation\\": \\"PutItem\\", @@ -675,6 +681,7 @@ $util.qr($ctx.stash.metadata.put(\\"modelObjectKey\\", { \\"version\\": \\"2018-05-29\\", \\"operation\\": \\"DeleteItem\\" } ) +$util.unauthorized() #if( $ctx.stash.metadata.modelObjectKey ) #set( $Key = $ctx.stash.metadata.modelObjectKey ) #else @@ -767,6 +774,7 @@ $util.qr($mergedValues.putAll($util.defaultIfNull($ctx.args.input, {}))) #set( $expSet = {} ) #set( $expAdd = {} ) #set( $expRemove = [] ) +$util.unauthorized() #if( $ctx.stash.metadata.modelObjectKey ) #set( $Key = $ctx.stash.metadata.modelObjectKey ) #else @@ -903,6 +911,7 @@ $util.qr($ctx.stash.metadata.put(\\"modelObjectKey\\", { \\"version\\": \\"2018-05-29\\", \\"operation\\": \\"GetItem\\" } ) +$util.unauthorized() #if( $ctx.stash.metadata.modelObjectKey ) #set( $key = $ctx.stash.metadata.modelObjectKey ) #else @@ -988,6 +997,7 @@ $util.qr($ctx.stash.put(\\"modelQueryExpression\\", $modelQueryExpression)) \\"version\\": \\"2018-05-29\\", \\"limit\\": $limit } ) +$util.unauthorized() #if( $context.args.nextToken ) #set( $ListRequest.nextToken = $context.args.nextToken ) #end @@ -1076,6 +1086,7 @@ $util.qr($ctx.stash.metadata.put(\\"modelObjectKey\\", { $util.qr($mergedValues.putAll($util.defaultIfNull($ctx.args.input, {}))) ## set the typename ** $util.qr($mergedValues.put(\\"__typename\\", \\"Test\\")) +$util.unauthorized() #set( $PutObject = { \\"version\\": \\"2018-05-29\\", \\"operation\\": \\"PutItem\\", @@ -1156,6 +1167,7 @@ $util.qr($ctx.stash.metadata.put(\\"modelObjectKey\\", { \\"version\\": \\"2018-05-29\\", \\"operation\\": \\"DeleteItem\\" } ) +$util.unauthorized() #if( $ctx.stash.metadata.modelObjectKey ) #set( $Key = $ctx.stash.metadata.modelObjectKey ) #else @@ -1247,6 +1259,7 @@ $util.qr($mergedValues.putAll($util.defaultIfNull($ctx.args.input, {}))) #set( $expSet = {} ) #set( $expAdd = {} ) #set( $expRemove = [] ) +$util.unauthorized() #if( $ctx.stash.metadata.modelObjectKey ) #set( $Key = $ctx.stash.metadata.modelObjectKey ) #else @@ -1382,6 +1395,7 @@ $util.qr($ctx.stash.metadata.put(\\"modelObjectKey\\", { \\"version\\": \\"2018-05-29\\", \\"operation\\": \\"GetItem\\" } ) +$util.unauthorized() #if( $ctx.stash.metadata.modelObjectKey ) #set( $key = $ctx.stash.metadata.modelObjectKey ) #else @@ -1424,6 +1438,7 @@ $util.qr($ctx.stash.put(\\"modelQueryExpression\\", $modelQueryExpression)) \\"version\\": \\"2018-05-29\\", \\"limit\\": $limit } ) +$util.unauthorized() #if( $context.args.nextToken ) #set( $ListRequest.nextToken = $context.args.nextToken ) #end @@ -1513,6 +1528,7 @@ $util.qr($ctx.stash.metadata.put(\\"modelObjectKey\\", { $util.qr($mergedValues.putAll($util.defaultIfNull($ctx.args.input, {}))) ## set the typename ** $util.qr($mergedValues.put(\\"__typename\\", \\"Test\\")) +$util.unauthorized() #set( $PutObject = { \\"version\\": \\"2018-05-29\\", \\"operation\\": \\"PutItem\\", @@ -1594,6 +1610,7 @@ $util.qr($ctx.stash.metadata.put(\\"modelObjectKey\\", { \\"version\\": \\"2018-05-29\\", \\"operation\\": \\"DeleteItem\\" } ) +$util.unauthorized() #if( $ctx.stash.metadata.modelObjectKey ) #set( $Key = $ctx.stash.metadata.modelObjectKey ) #else @@ -1686,6 +1703,7 @@ $util.qr($mergedValues.putAll($util.defaultIfNull($ctx.args.input, {}))) #set( $expSet = {} ) #set( $expAdd = {} ) #set( $expRemove = [] ) +$util.unauthorized() #if( $ctx.stash.metadata.modelObjectKey ) #set( $Key = $ctx.stash.metadata.modelObjectKey ) #else @@ -1822,6 +1840,7 @@ $util.qr($ctx.stash.metadata.put(\\"modelObjectKey\\", { \\"version\\": \\"2018-05-29\\", \\"operation\\": \\"GetItem\\" } ) +$util.unauthorized() #if( $ctx.stash.metadata.modelObjectKey ) #set( $key = $ctx.stash.metadata.modelObjectKey ) #else @@ -1907,6 +1926,7 @@ $util.qr($ctx.stash.put(\\"modelQueryExpression\\", $modelQueryExpression)) \\"version\\": \\"2018-05-29\\", \\"limit\\": $limit } ) +$util.unauthorized() #if( $context.args.nextToken ) #set( $ListRequest.nextToken = $context.args.nextToken ) #end @@ -1996,6 +2016,7 @@ $util.qr($ctx.stash.metadata.put(\\"modelObjectKey\\", { $util.qr($mergedValues.putAll($util.defaultIfNull($ctx.args.input, {}))) ## set the typename ** $util.qr($mergedValues.put(\\"__typename\\", \\"Test\\")) +$util.unauthorized() #set( $PutObject = { \\"version\\": \\"2018-05-29\\", \\"operation\\": \\"PutItem\\", @@ -2077,6 +2098,7 @@ $util.qr($ctx.stash.metadata.put(\\"modelObjectKey\\", { \\"version\\": \\"2018-05-29\\", \\"operation\\": \\"DeleteItem\\" } ) +$util.unauthorized() #if( $ctx.stash.metadata.modelObjectKey ) #set( $Key = $ctx.stash.metadata.modelObjectKey ) #else @@ -2185,6 +2207,7 @@ $util.qr($ctx.stash.metadata.put(\\"modelObjectKey\\", { $util.qr($mergedValues.putAll($util.defaultIfNull($ctx.args.input, {}))) ## set the typename ** $util.qr($mergedValues.put(\\"__typename\\", \\"Test\\")) +$util.unauthorized() #set( $PutObject = { \\"version\\": \\"2018-05-29\\", \\"operation\\": \\"PutItem\\", @@ -2266,6 +2289,7 @@ $util.qr($ctx.stash.metadata.put(\\"modelObjectKey\\", { \\"version\\": \\"2018-05-29\\", \\"operation\\": \\"DeleteItem\\" } ) +$util.unauthorized() #if( $ctx.stash.metadata.modelObjectKey ) #set( $Key = $ctx.stash.metadata.modelObjectKey ) #else @@ -2358,6 +2382,7 @@ $util.qr($mergedValues.putAll($util.defaultIfNull($ctx.args.input, {}))) #set( $expSet = {} ) #set( $expAdd = {} ) #set( $expRemove = [] ) +$util.unauthorized() #if( $ctx.stash.metadata.modelObjectKey ) #set( $Key = $ctx.stash.metadata.modelObjectKey ) #else @@ -2515,6 +2540,7 @@ $util.qr($mergedValues.putAll($util.defaultIfNull($ctx.args.input, {}))) #set( $expSet = {} ) #set( $expAdd = {} ) #set( $expRemove = [] ) +$util.unauthorized() #if( $ctx.stash.metadata.modelObjectKey ) #set( $Key = $ctx.stash.metadata.modelObjectKey ) #else @@ -2650,6 +2676,7 @@ $util.qr($ctx.stash.metadata.put(\\"modelObjectKey\\", { \\"version\\": \\"2018-05-29\\", \\"operation\\": \\"GetItem\\" } ) +$util.unauthorized() #if( $ctx.stash.metadata.modelObjectKey ) #set( $key = $ctx.stash.metadata.modelObjectKey ) #else @@ -2692,6 +2719,7 @@ $util.qr($ctx.stash.put(\\"modelQueryExpression\\", $modelQueryExpression)) \\"version\\": \\"2018-05-29\\", \\"limit\\": $limit } ) +$util.unauthorized() #if( $context.args.nextToken ) #set( $ListRequest.nextToken = $context.args.nextToken ) #end @@ -2739,6 +2767,7 @@ $util.qr($ctx.stash.metadata.put(\\"modelObjectKey\\", { \\"version\\": \\"2018-05-29\\", \\"operation\\": \\"GetItem\\" } ) +$util.unauthorized() #if( $ctx.stash.metadata.modelObjectKey ) #set( $key = $ctx.stash.metadata.modelObjectKey ) #else @@ -2824,6 +2853,7 @@ $util.qr($ctx.stash.put(\\"modelQueryExpression\\", $modelQueryExpression)) \\"version\\": \\"2018-05-29\\", \\"limit\\": $limit } ) +$util.unauthorized() #if( $context.args.nextToken ) #set( $ListRequest.nextToken = $context.args.nextToken ) #end @@ -2912,6 +2942,7 @@ $util.qr($ctx.stash.metadata.put(\\"modelObjectKey\\", { $util.qr($mergedValues.putAll($util.defaultIfNull($ctx.args.input, {}))) ## set the typename ** $util.qr($mergedValues.put(\\"__typename\\", \\"Test\\")) +$util.unauthorized() #set( $PutObject = { \\"version\\": \\"2018-05-29\\", \\"operation\\": \\"PutItem\\", @@ -2992,6 +3023,7 @@ $util.qr($ctx.stash.metadata.put(\\"modelObjectKey\\", { \\"version\\": \\"2018-05-29\\", \\"operation\\": \\"DeleteItem\\" } ) +$util.unauthorized() #if( $ctx.stash.metadata.modelObjectKey ) #set( $Key = $ctx.stash.metadata.modelObjectKey ) #else @@ -3100,6 +3132,7 @@ $util.qr($ctx.stash.metadata.put(\\"modelObjectKey\\", { $util.qr($mergedValues.putAll($util.defaultIfNull($ctx.args.input, {}))) ## set the typename ** $util.qr($mergedValues.put(\\"__typename\\", \\"Test\\")) +$util.unauthorized() #set( $PutObject = { \\"version\\": \\"2018-05-29\\", \\"operation\\": \\"PutItem\\", @@ -3181,6 +3214,7 @@ $util.qr($ctx.stash.metadata.put(\\"modelObjectKey\\", { \\"version\\": \\"2018-05-29\\", \\"operation\\": \\"DeleteItem\\" } ) +$util.unauthorized() #if( $ctx.stash.metadata.modelObjectKey ) #set( $Key = $ctx.stash.metadata.modelObjectKey ) #else @@ -3273,6 +3307,7 @@ $util.qr($mergedValues.putAll($util.defaultIfNull($ctx.args.input, {}))) #set( $expSet = {} ) #set( $expAdd = {} ) #set( $expRemove = [] ) +$util.unauthorized() #if( $ctx.stash.metadata.modelObjectKey ) #set( $Key = $ctx.stash.metadata.modelObjectKey ) #else @@ -3429,6 +3464,7 @@ $util.qr($mergedValues.putAll($util.defaultIfNull($ctx.args.input, {}))) #set( $expSet = {} ) #set( $expAdd = {} ) #set( $expRemove = [] ) +$util.unauthorized() #if( $ctx.stash.metadata.modelObjectKey ) #set( $Key = $ctx.stash.metadata.modelObjectKey ) #else @@ -3564,6 +3600,7 @@ $util.qr($ctx.stash.metadata.put(\\"modelObjectKey\\", { \\"version\\": \\"2018-05-29\\", \\"operation\\": \\"GetItem\\" } ) +$util.unauthorized() #if( $ctx.stash.metadata.modelObjectKey ) #set( $key = $ctx.stash.metadata.modelObjectKey ) #else @@ -3606,6 +3643,7 @@ $util.qr($ctx.stash.put(\\"modelQueryExpression\\", $modelQueryExpression)) \\"version\\": \\"2018-05-29\\", \\"limit\\": $limit } ) +$util.unauthorized() #if( $context.args.nextToken ) #set( $ListRequest.nextToken = $context.args.nextToken ) #end @@ -3653,6 +3691,7 @@ $util.qr($ctx.stash.metadata.put(\\"modelObjectKey\\", { \\"version\\": \\"2018-05-29\\", \\"operation\\": \\"GetItem\\" } ) +$util.unauthorized() #if( $ctx.stash.metadata.modelObjectKey ) #set( $key = $ctx.stash.metadata.modelObjectKey ) #else @@ -3738,6 +3777,7 @@ $util.qr($ctx.stash.put(\\"modelQueryExpression\\", $modelQueryExpression)) \\"version\\": \\"2018-05-29\\", \\"limit\\": $limit } ) +$util.unauthorized() #if( $context.args.nextToken ) #set( $ListRequest.nextToken = $context.args.nextToken ) #end diff --git a/packages/amplify-graphql-model-transformer/src/__tests__/__snapshots__/model-transformer.test.ts.snap b/packages/amplify-graphql-model-transformer/src/__tests__/__snapshots__/model-transformer.test.ts.snap index 602863fbac1..11271528691 100644 --- a/packages/amplify-graphql-model-transformer/src/__tests__/__snapshots__/model-transformer.test.ts.snap +++ b/packages/amplify-graphql-model-transformer/src/__tests__/__snapshots__/model-transformer.test.ts.snap @@ -772,6 +772,7 @@ exports[`ModelTransformer: should have timestamps as nullable fields when the t $util.qr($mergedValues.putAll($util.defaultIfNull($ctx.args.input, {}))) ## set the typename ** $util.qr($mergedValues.put(\\"__typename\\", \\"Post\\")) +$util.unauthorized() #set( $PutObject = { \\"version\\": \\"2018-05-29\\", \\"operation\\": \\"PutItem\\", @@ -845,6 +846,7 @@ $util.qr($mergedValues.putAll($util.defaultIfNull($ctx.args.input, {}))) #set( $expSet = {} ) #set( $expAdd = {} ) #set( $expRemove = [] ) +$util.unauthorized() #if( $ctx.stash.metadata.modelObjectKey ) #set( $Key = $ctx.stash.metadata.modelObjectKey ) #else @@ -991,6 +993,7 @@ exports[`ModelTransformer: should not add default primary key when ID is define $util.qr($mergedValues.putAll($util.defaultIfNull($ctx.args.input, {}))) ## set the typename ** $util.qr($mergedValues.put(\\"__typename\\", \\"Post\\")) +$util.unauthorized() #set( $PutObject = { \\"version\\": \\"2018-05-29\\", \\"operation\\": \\"PutItem\\", @@ -1347,6 +1350,7 @@ exports[`ModelTransformer: should not to auto generate createdAt and updatedAt $util.qr($mergedValues.putAll($util.defaultIfNull($ctx.args.input, {}))) ## set the typename ** $util.qr($mergedValues.put(\\"__typename\\", \\"Post\\")) +$util.unauthorized() #set( $PutObject = { \\"version\\": \\"2018-05-29\\", \\"operation\\": \\"PutItem\\", @@ -1420,6 +1424,7 @@ $util.qr($mergedValues.putAll($util.defaultIfNull($ctx.args.input, {}))) #set( $expSet = {} ) #set( $expAdd = {} ) #set( $expRemove = [] ) +$util.unauthorized() #if( $ctx.stash.metadata.modelObjectKey ) #set( $Key = $ctx.stash.metadata.modelObjectKey ) #else @@ -1718,6 +1723,7 @@ exports[`ModelTransformer: should not to include createdAt and updatedAt field $util.qr($mergedValues.putAll($util.defaultIfNull($ctx.args.input, {}))) ## set the typename ** $util.qr($mergedValues.put(\\"__typename\\", \\"Post\\")) +$util.unauthorized() #set( $PutObject = { \\"version\\": \\"2018-05-29\\", \\"operation\\": \\"PutItem\\", @@ -1791,6 +1797,7 @@ $util.qr($mergedValues.putAll($util.defaultIfNull($ctx.args.input, {}))) #set( $expSet = {} ) #set( $expAdd = {} ) #set( $expRemove = [] ) +$util.unauthorized() #if( $ctx.stash.metadata.modelObjectKey ) #set( $Key = $ctx.stash.metadata.modelObjectKey ) #else @@ -2091,6 +2098,7 @@ exports[`ModelTransformer: should support timestamp parameters when generating $util.qr($mergedValues.putAll($util.defaultIfNull($ctx.args.input, {}))) ## set the typename ** $util.qr($mergedValues.put(\\"__typename\\", \\"Post\\")) +$util.unauthorized() #set( $PutObject = { \\"version\\": \\"2018-05-29\\", \\"operation\\": \\"PutItem\\", @@ -2164,6 +2172,7 @@ $util.qr($mergedValues.putAll($util.defaultIfNull($ctx.args.input, {}))) #set( $expSet = {} ) #set( $expAdd = {} ) #set( $expRemove = [] ) +$util.unauthorized() #if( $ctx.stash.metadata.modelObjectKey ) #set( $Key = $ctx.stash.metadata.modelObjectKey ) #else diff --git a/packages/amplify-graphql-model-transformer/src/__tests__/model-transformer.test.ts b/packages/amplify-graphql-model-transformer/src/__tests__/model-transformer.test.ts index a6b2a08acf3..4ddf9d7d8e6 100644 --- a/packages/amplify-graphql-model-transformer/src/__tests__/model-transformer.test.ts +++ b/packages/amplify-graphql-model-transformer/src/__tests__/model-transformer.test.ts @@ -879,4 +879,25 @@ describe('ModelTransformer: ', () => { expect(out).toBeDefined(); validateModelSchema(parse(out.schema)); }); + + it.skip('should support global sandbox mode', () => { + const validSchema = ` + type AMPLIFY_GLOBAL @allow_public_data_access_with_api_key(in: \"dev\") + + type Post @model { + id: ID! + title: String! + } + `; + + const transformer = new GraphQLTransform({ + transformers: [new ModelTransformer()], + featureFlags, + }); + const out = transformer.transform(validSchema); + expect(out).toBeDefined(); + + validateModelSchema(parse(out.schema)); + parse(out.schema); + }); }); diff --git a/packages/amplify-graphql-model-transformer/src/graphql-model-transformer.ts b/packages/amplify-graphql-model-transformer/src/graphql-model-transformer.ts index 6e3097bceba..0f3cc38dcb0 100644 --- a/packages/amplify-graphql-model-transformer/src/graphql-model-transformer.ts +++ b/packages/amplify-graphql-model-transformer/src/graphql-model-transformer.ts @@ -371,7 +371,7 @@ export class ModelTransformer extends TransformerModelBase implements Transforme typeName, fieldName, dataSource, - MappingTemplate.s3MappingTemplateFromString(generateGetRequestTemplate(), `${typeName}.${fieldName}.req.vtl`), + MappingTemplate.s3MappingTemplateFromString(generateGetRequestTemplate(ctx), `${typeName}.${fieldName}.req.vtl`), MappingTemplate.s3MappingTemplateFromString(generateDefaultResponseMappingTemplate(), `${typeName}.${fieldName}.res.vtl`), ); } @@ -391,7 +391,7 @@ export class ModelTransformer extends TransformerModelBase implements Transforme typeName, fieldName, dataSource, - MappingTemplate.s3MappingTemplateFromString(generateListRequestTemplate(), `${typeName}.${fieldName}.req.vtl`), + MappingTemplate.s3MappingTemplateFromString(generateListRequestTemplate(ctx), `${typeName}.${fieldName}.req.vtl`), MappingTemplate.s3MappingTemplateFromString(generateDefaultResponseMappingTemplate(), `${typeName}.${fieldName}.res.vtl`), ); } @@ -411,7 +411,7 @@ export class ModelTransformer extends TransformerModelBase implements Transforme typeName, fieldName, dataSource, - MappingTemplate.s3MappingTemplateFromString(generateUpdateRequestTemplate(typeName), `${typeName}.${fieldName}.req.vtl`), + MappingTemplate.s3MappingTemplateFromString(generateUpdateRequestTemplate(typeName, ctx), `${typeName}.${fieldName}.req.vtl`), MappingTemplate.s3MappingTemplateFromString(generateDefaultResponseMappingTemplate(), `${typeName}.${fieldName}.res.vtl`), ); // Todo: get the slot index from the resolver to keep the name unique and show the order of functions @@ -439,7 +439,7 @@ export class ModelTransformer extends TransformerModelBase implements Transforme typeName, fieldName, dataSource, - MappingTemplate.s3MappingTemplateFromString(generateDeleteRequestTemplate(), `${typeName}.${fieldName}.req.vtl`), + MappingTemplate.s3MappingTemplateFromString(generateDeleteRequestTemplate(ctx), `${typeName}.${fieldName}.req.vtl`), MappingTemplate.s3MappingTemplateFromString(generateDefaultResponseMappingTemplate(), `${typeName}.${fieldName}.res.vtl`), ); } @@ -738,7 +738,10 @@ export class ModelTransformer extends TransformerModelBase implements Transforme typeName, fieldName, dataSource, - MappingTemplate.s3MappingTemplateFromString(generateCreateRequestTemplate(type.name.value), `${typeName}.${fieldName}.req.vtl`), + MappingTemplate.s3MappingTemplateFromString( + generateCreateRequestTemplate(type.name.value, ctx), + `${typeName}.${fieldName}.req.vtl`, + ), MappingTemplate.s3MappingTemplateFromString(generateDefaultResponseMappingTemplate(), `${typeName}.${fieldName}.res.vtl`), ); this.resolverMap[resolverKey] = resolver; diff --git a/packages/amplify-graphql-model-transformer/src/resolvers/common.ts b/packages/amplify-graphql-model-transformer/src/resolvers/common.ts index 2d470bd82e2..9d836193058 100644 --- a/packages/amplify-graphql-model-transformer/src/resolvers/common.ts +++ b/packages/amplify-graphql-model-transformer/src/resolvers/common.ts @@ -15,6 +15,7 @@ import { ifElse, printBlock, toJson, + str, } from 'graphql-mapping-template'; /** @@ -67,10 +68,20 @@ export const generateDefaultResponseMappingTemplate = (): string => { }; /** - * Util function to gernate resolver key used to keep track of all the resolvers in memory + * Util function to generate resolver key used to keep track of all the resolvers in memory * @param typeName Name of the type * @param fieldName Name of the field */ export const generateResolverKey = (typeName: string, fieldName: string): string => { return `${typeName}.${fieldName}`; }; + +/** + * Util function to generate sandbox mode expression + * @param inputCondition boolean to enable sandbox mode + */ +export const generateSandboxMode = (ctx: any): Expression => { + if (ctx.resourceHelper.api.globalSandboxModeEnabled) + return iff(notEquals(methodCall(ref('util.authType')), str('API_KEY')), methodCall(ref('util.unauthorized'))); + else return methodCall(ref('util.unauthorized')); +}; diff --git a/packages/amplify-graphql-model-transformer/src/resolvers/mutation.ts b/packages/amplify-graphql-model-transformer/src/resolvers/mutation.ts index 52fa7f06dc7..e5544b82429 100644 --- a/packages/amplify-graphql-model-transformer/src/resolvers/mutation.ts +++ b/packages/amplify-graphql-model-transformer/src/resolvers/mutation.ts @@ -19,13 +19,13 @@ import { printBlock, } from 'graphql-mapping-template'; import { ModelDirectiveConfiguration } from '../graphql-model-transformer'; -import { generateConditionSlot } from './common'; +import { generateConditionSlot, generateSandboxMode } from './common'; /** * Generates VTL template in update mutation * @param modelName Name of the model */ -export const generateUpdateRequestTemplate = (modelName: string): string => { +export const generateUpdateRequestTemplate = (modelName: string, ctx: any): string => { const objectKeyVariable = 'ctx.stash.metadata.modelObjectKey'; const keyFields: StringNode[] = [str('id')]; const statements: Expression[] = [ @@ -42,6 +42,8 @@ export const generateUpdateRequestTemplate = (modelName: string): string => { set(ref('expAdd'), obj({})), set(ref('expRemove'), list([])), + generateSandboxMode(ctx), + ifElse( ref(objectKeyVariable), set(ref('Key'), ref(objectKeyVariable)), @@ -144,7 +146,7 @@ export const generateUpdateRequestTemplate = (modelName: string): string => { * Generates VTL template in create mutation * @param modelName Name of the model */ -export const generateCreateRequestTemplate = (modelName: string): string => { +export const generateCreateRequestTemplate = (modelName: string, ctx: any): string => { const statements: Expression[] = [ // set key the condition ...generateKeyConditionTemplate(false), @@ -156,6 +158,8 @@ export const generateCreateRequestTemplate = (modelName: string): string => { comment('set the typename'), qref(methodCall(ref('mergedValues.put'), str('__typename'), str(modelName))), + generateSandboxMode(ctx), + // Set PutObject set( ref('PutObject'), @@ -240,7 +244,7 @@ export const generateCreateInitSlotTemplate = (name: string, modelConfig: ModelD * Generates VTL template in delete mutation * */ -export const generateDeleteRequestTemplate = (): string => { +export const generateDeleteRequestTemplate = (ctx: any): string => { const statements: Expression[] = [ set( ref('DeleteRequest'), @@ -249,6 +253,7 @@ export const generateDeleteRequestTemplate = (): string => { operation: str('DeleteItem'), }), ), + generateSandboxMode(ctx), ifElse( ref('ctx.stash.metadata.modelObjectKey'), set(ref('Key'), ref('ctx.stash.metadata.modelObjectKey')), diff --git a/packages/amplify-graphql-model-transformer/src/resolvers/query.ts b/packages/amplify-graphql-model-transformer/src/resolvers/query.ts index d42dd33ab9f..3c676806da7 100644 --- a/packages/amplify-graphql-model-transformer/src/resolvers/query.ts +++ b/packages/amplify-graphql-model-transformer/src/resolvers/query.ts @@ -17,13 +17,15 @@ import { bool, and, } from 'graphql-mapping-template'; +import { generateSandboxMode } from './common'; /** * Generate get query resolver template */ -export const generateGetRequestTemplate = (): string => { +export const generateGetRequestTemplate = (ctx: any): string => { const statements: Expression[] = [ set(ref('GetRequest'), obj({ version: str('2018-05-29'), operation: str('GetItem') })), + generateSandboxMode(ctx), ifElse( ref('ctx.stash.metadata.modelObjectKey'), set(ref('key'), ref('ctx.stash.metadata.modelObjectKey')), @@ -36,7 +38,7 @@ export const generateGetRequestTemplate = (): string => { return printBlock('Get Request template')(compoundExpression(statements)); }; -export const generateListRequestTemplate = (): string => { +export const generateListRequestTemplate = (ctx: any): string => { const requestVariable = 'ListRequest'; const modelQueryObj = 'ctx.stash.modelQueryExpression'; const indexNameVariable = 'ctx.stash.metadata.index'; @@ -49,6 +51,7 @@ export const generateListRequestTemplate = (): string => { limit: ref('limit'), }), ), + generateSandboxMode(ctx), iff(ref('context.args.nextToken'), set(ref(`${requestVariable}.nextToken`), ref('context.args.nextToken'))), iff( ref('context.args.filter'), diff --git a/packages/amplify-graphql-relational-transformer/src/__tests__/__snapshots__/amplify-graphql-has-many-transformer.test.ts.snap b/packages/amplify-graphql-relational-transformer/src/__tests__/__snapshots__/amplify-graphql-has-many-transformer.test.ts.snap index d06564b1739..59f18bd24b1 100644 --- a/packages/amplify-graphql-relational-transformer/src/__tests__/__snapshots__/amplify-graphql-has-many-transformer.test.ts.snap +++ b/packages/amplify-graphql-relational-transformer/src/__tests__/__snapshots__/amplify-graphql-has-many-transformer.test.ts.snap @@ -8213,6 +8213,7 @@ $util.qr($ctx.stash.metadata.put(\\"modelObjectKey\\", { $util.qr($mergedValues.putAll($util.defaultIfNull($ctx.args.input, {}))) ## set the typename ** $util.qr($mergedValues.put(\\"__typename\\", \\"Child\\")) +$util.unauthorized() #set( $PutObject = { \\"version\\": \\"2018-05-29\\", \\"operation\\": \\"PutItem\\", @@ -8315,6 +8316,7 @@ $util.toJson({ $util.qr($mergedValues.putAll($util.defaultIfNull($ctx.args.input, {}))) ## set the typename ** $util.qr($mergedValues.put(\\"__typename\\", \\"Comment\\")) +$util.unauthorized() #set( $PutObject = { \\"version\\": \\"2018-05-29\\", \\"operation\\": \\"PutItem\\", @@ -8417,6 +8419,7 @@ $util.toJson({ $util.qr($mergedValues.putAll($util.defaultIfNull($ctx.args.input, {}))) ## set the typename ** $util.qr($mergedValues.put(\\"__typename\\", \\"Friendship\\")) +$util.unauthorized() #set( $PutObject = { \\"version\\": \\"2018-05-29\\", \\"operation\\": \\"PutItem\\", @@ -8519,6 +8522,7 @@ $util.toJson({ $util.qr($mergedValues.putAll($util.defaultIfNull($ctx.args.input, {}))) ## set the typename ** $util.qr($mergedValues.put(\\"__typename\\", \\"Parent\\")) +$util.unauthorized() #set( $PutObject = { \\"version\\": \\"2018-05-29\\", \\"operation\\": \\"PutItem\\", @@ -8632,6 +8636,7 @@ $util.qr($ctx.stash.metadata.put(\\"modelObjectKey\\", { $util.qr($mergedValues.putAll($util.defaultIfNull($ctx.args.input, {}))) ## set the typename ** $util.qr($mergedValues.put(\\"__typename\\", \\"Post\\")) +$util.unauthorized() #set( $PutObject = { \\"version\\": \\"2018-05-29\\", \\"operation\\": \\"PutItem\\", @@ -8734,6 +8739,7 @@ $util.toJson({ $util.qr($mergedValues.putAll($util.defaultIfNull($ctx.args.input, {}))) ## set the typename ** $util.qr($mergedValues.put(\\"__typename\\", \\"PostAuthor\\")) +$util.unauthorized() #set( $PutObject = { \\"version\\": \\"2018-05-29\\", \\"operation\\": \\"PutItem\\", @@ -8836,6 +8842,7 @@ $util.toJson({ $util.qr($mergedValues.putAll($util.defaultIfNull($ctx.args.input, {}))) ## set the typename ** $util.qr($mergedValues.put(\\"__typename\\", \\"PostEditor\\")) +$util.unauthorized() #set( $PutObject = { \\"version\\": \\"2018-05-29\\", \\"operation\\": \\"PutItem\\", @@ -8938,6 +8945,7 @@ $util.toJson({ $util.qr($mergedValues.putAll($util.defaultIfNull($ctx.args.input, {}))) ## set the typename ** $util.qr($mergedValues.put(\\"__typename\\", \\"PostModel\\")) +$util.unauthorized() #set( $PutObject = { \\"version\\": \\"2018-05-29\\", \\"operation\\": \\"PutItem\\", @@ -9040,6 +9048,7 @@ $util.toJson({ $util.qr($mergedValues.putAll($util.defaultIfNull($ctx.args.input, {}))) ## set the typename ** $util.qr($mergedValues.put(\\"__typename\\", \\"Test\\")) +$util.unauthorized() #set( $PutObject = { \\"version\\": \\"2018-05-29\\", \\"operation\\": \\"PutItem\\", @@ -9161,6 +9170,7 @@ $util.qr($ctx.args.input.put(\\"email#name\\",\\"\${mergedValues.email}#\${merge $util.qr($mergedValues.putAll($util.defaultIfNull($ctx.args.input, {}))) ## set the typename ** $util.qr($mergedValues.put(\\"__typename\\", \\"Test1\\")) +$util.unauthorized() #set( $PutObject = { \\"version\\": \\"2018-05-29\\", \\"operation\\": \\"PutItem\\", @@ -9282,6 +9292,7 @@ $util.qr($ctx.args.input.put(\\"name#surname\\",\\"\${mergedValues.name}#\${merg $util.qr($mergedValues.putAll($util.defaultIfNull($ctx.args.input, {}))) ## set the typename ** $util.qr($mergedValues.put(\\"__typename\\", \\"User\\")) +$util.unauthorized() #set( $PutObject = { \\"version\\": \\"2018-05-29\\", \\"operation\\": \\"PutItem\\", @@ -9423,6 +9434,7 @@ $util.qr($mergedValues.putAll($util.defaultIfNull($ctx.args.input, {}))) $util.qr($mergedValues.putAll($util.defaultIfNull($ctx.args.input, {}))) ## set the typename ** $util.qr($mergedValues.put(\\"__typename\\", \\"UserModel\\")) +$util.unauthorized() #set( $PutObject = { \\"version\\": \\"2018-05-29\\", \\"operation\\": \\"PutItem\\", @@ -9504,6 +9516,7 @@ $util.qr($ctx.stash.metadata.put(\\"modelObjectKey\\", { \\"version\\": \\"2018-05-29\\", \\"operation\\": \\"DeleteItem\\" } ) +$util.unauthorized() #if( $ctx.stash.metadata.modelObjectKey ) #set( $Key = $ctx.stash.metadata.modelObjectKey ) #else @@ -9568,6 +9581,7 @@ $util.toJson($DeleteRequest) \\"version\\": \\"2018-05-29\\", \\"operation\\": \\"DeleteItem\\" } ) +$util.unauthorized() #if( $ctx.stash.metadata.modelObjectKey ) #set( $Key = $ctx.stash.metadata.modelObjectKey ) #else @@ -9632,6 +9646,7 @@ $util.toJson($DeleteRequest) \\"version\\": \\"2018-05-29\\", \\"operation\\": \\"DeleteItem\\" } ) +$util.unauthorized() #if( $ctx.stash.metadata.modelObjectKey ) #set( $Key = $ctx.stash.metadata.modelObjectKey ) #else @@ -9696,6 +9711,7 @@ $util.toJson($DeleteRequest) \\"version\\": \\"2018-05-29\\", \\"operation\\": \\"DeleteItem\\" } ) +$util.unauthorized() #if( $ctx.stash.metadata.modelObjectKey ) #set( $Key = $ctx.stash.metadata.modelObjectKey ) #else @@ -9770,6 +9786,7 @@ $util.qr($ctx.stash.metadata.put(\\"modelObjectKey\\", { \\"version\\": \\"2018-05-29\\", \\"operation\\": \\"DeleteItem\\" } ) +$util.unauthorized() #if( $ctx.stash.metadata.modelObjectKey ) #set( $Key = $ctx.stash.metadata.modelObjectKey ) #else @@ -9834,6 +9851,7 @@ $util.toJson($DeleteRequest) \\"version\\": \\"2018-05-29\\", \\"operation\\": \\"DeleteItem\\" } ) +$util.unauthorized() #if( $ctx.stash.metadata.modelObjectKey ) #set( $Key = $ctx.stash.metadata.modelObjectKey ) #else @@ -9898,6 +9916,7 @@ $util.toJson($DeleteRequest) \\"version\\": \\"2018-05-29\\", \\"operation\\": \\"DeleteItem\\" } ) +$util.unauthorized() #if( $ctx.stash.metadata.modelObjectKey ) #set( $Key = $ctx.stash.metadata.modelObjectKey ) #else @@ -9962,6 +9981,7 @@ $util.toJson($DeleteRequest) \\"version\\": \\"2018-05-29\\", \\"operation\\": \\"DeleteItem\\" } ) +$util.unauthorized() #if( $ctx.stash.metadata.modelObjectKey ) #set( $Key = $ctx.stash.metadata.modelObjectKey ) #else @@ -10026,6 +10046,7 @@ $util.toJson($DeleteRequest) \\"version\\": \\"2018-05-29\\", \\"operation\\": \\"DeleteItem\\" } ) +$util.unauthorized() #if( $ctx.stash.metadata.modelObjectKey ) #set( $Key = $ctx.stash.metadata.modelObjectKey ) #else @@ -10101,6 +10122,7 @@ $util.qr($ctx.stash.metadata.put(\\"modelObjectKey\\", { \\"version\\": \\"2018-05-29\\", \\"operation\\": \\"DeleteItem\\" } ) +$util.unauthorized() #if( $ctx.stash.metadata.modelObjectKey ) #set( $Key = $ctx.stash.metadata.modelObjectKey ) #else @@ -10176,6 +10198,7 @@ $util.qr($ctx.stash.metadata.put(\\"modelObjectKey\\", { \\"version\\": \\"2018-05-29\\", \\"operation\\": \\"DeleteItem\\" } ) +$util.unauthorized() #if( $ctx.stash.metadata.modelObjectKey ) #set( $Key = $ctx.stash.metadata.modelObjectKey ) #else @@ -10264,6 +10287,7 @@ $util.qr($ctx.args.input.put(\\"name#surname\\",\\"\${mergedValues.name}#\${merg \\"version\\": \\"2018-05-29\\", \\"operation\\": \\"DeleteItem\\" } ) +$util.unauthorized() #if( $ctx.stash.metadata.modelObjectKey ) #set( $Key = $ctx.stash.metadata.modelObjectKey ) #else @@ -10356,6 +10380,7 @@ $util.qr($mergedValues.putAll($util.defaultIfNull($ctx.args.input, {}))) #set( $expSet = {} ) #set( $expAdd = {} ) #set( $expRemove = [] ) +$util.unauthorized() #if( $ctx.stash.metadata.modelObjectKey ) #set( $Key = $ctx.stash.metadata.modelObjectKey ) #else @@ -10501,6 +10526,7 @@ $util.qr($mergedValues.putAll($util.defaultIfNull($ctx.args.input, {}))) #set( $expSet = {} ) #set( $expAdd = {} ) #set( $expRemove = [] ) +$util.unauthorized() #if( $ctx.stash.metadata.modelObjectKey ) #set( $Key = $ctx.stash.metadata.modelObjectKey ) #else @@ -10646,6 +10672,7 @@ $util.qr($mergedValues.putAll($util.defaultIfNull($ctx.args.input, {}))) #set( $expSet = {} ) #set( $expAdd = {} ) #set( $expRemove = [] ) +$util.unauthorized() #if( $ctx.stash.metadata.modelObjectKey ) #set( $Key = $ctx.stash.metadata.modelObjectKey ) #else @@ -10791,6 +10818,7 @@ $util.qr($mergedValues.putAll($util.defaultIfNull($ctx.args.input, {}))) #set( $expSet = {} ) #set( $expAdd = {} ) #set( $expRemove = [] ) +$util.unauthorized() #if( $ctx.stash.metadata.modelObjectKey ) #set( $Key = $ctx.stash.metadata.modelObjectKey ) #else @@ -10947,6 +10975,7 @@ $util.qr($mergedValues.putAll($util.defaultIfNull($ctx.args.input, {}))) #set( $expSet = {} ) #set( $expAdd = {} ) #set( $expRemove = [] ) +$util.unauthorized() #if( $ctx.stash.metadata.modelObjectKey ) #set( $Key = $ctx.stash.metadata.modelObjectKey ) #else @@ -11092,6 +11121,7 @@ $util.qr($mergedValues.putAll($util.defaultIfNull($ctx.args.input, {}))) #set( $expSet = {} ) #set( $expAdd = {} ) #set( $expRemove = [] ) +$util.unauthorized() #if( $ctx.stash.metadata.modelObjectKey ) #set( $Key = $ctx.stash.metadata.modelObjectKey ) #else @@ -11237,6 +11267,7 @@ $util.qr($mergedValues.putAll($util.defaultIfNull($ctx.args.input, {}))) #set( $expSet = {} ) #set( $expAdd = {} ) #set( $expRemove = [] ) +$util.unauthorized() #if( $ctx.stash.metadata.modelObjectKey ) #set( $Key = $ctx.stash.metadata.modelObjectKey ) #else @@ -11382,6 +11413,7 @@ $util.qr($mergedValues.putAll($util.defaultIfNull($ctx.args.input, {}))) #set( $expSet = {} ) #set( $expAdd = {} ) #set( $expRemove = [] ) +$util.unauthorized() #if( $ctx.stash.metadata.modelObjectKey ) #set( $Key = $ctx.stash.metadata.modelObjectKey ) #else @@ -11527,6 +11559,7 @@ $util.qr($mergedValues.putAll($util.defaultIfNull($ctx.args.input, {}))) #set( $expSet = {} ) #set( $expAdd = {} ) #set( $expRemove = [] ) +$util.unauthorized() #if( $ctx.stash.metadata.modelObjectKey ) #set( $Key = $ctx.stash.metadata.modelObjectKey ) #else @@ -11691,6 +11724,7 @@ $util.qr($mergedValues.putAll($util.defaultIfNull($ctx.args.input, {}))) #set( $expSet = {} ) #set( $expAdd = {} ) #set( $expRemove = [] ) +$util.unauthorized() #if( $ctx.stash.metadata.modelObjectKey ) #set( $Key = $ctx.stash.metadata.modelObjectKey ) #else @@ -11855,6 +11889,7 @@ $util.qr($mergedValues.putAll($util.defaultIfNull($ctx.args.input, {}))) #set( $expSet = {} ) #set( $expAdd = {} ) #set( $expRemove = [] ) +$util.unauthorized() #if( $ctx.stash.metadata.modelObjectKey ) #set( $Key = $ctx.stash.metadata.modelObjectKey ) #else @@ -12039,6 +12074,7 @@ $util.qr($mergedValues.putAll($util.defaultIfNull($ctx.args.input, {}))) #set( $expSet = {} ) #set( $expAdd = {} ) #set( $expRemove = [] ) +$util.unauthorized() #if( $ctx.stash.metadata.modelObjectKey ) #set( $Key = $ctx.stash.metadata.modelObjectKey ) #else @@ -12577,6 +12613,7 @@ $util.qr($ctx.stash.metadata.put(\\"modelObjectKey\\", { \\"version\\": \\"2018-05-29\\", \\"operation\\": \\"GetItem\\" } ) +$util.unauthorized() #if( $ctx.stash.metadata.modelObjectKey ) #set( $key = $ctx.stash.metadata.modelObjectKey ) #else @@ -12599,6 +12636,7 @@ $util.toJson($GetRequest) \\"version\\": \\"2018-05-29\\", \\"operation\\": \\"GetItem\\" } ) +$util.unauthorized() #if( $ctx.stash.metadata.modelObjectKey ) #set( $key = $ctx.stash.metadata.modelObjectKey ) #else @@ -12621,6 +12659,7 @@ $util.toJson($GetRequest) \\"version\\": \\"2018-05-29\\", \\"operation\\": \\"GetItem\\" } ) +$util.unauthorized() #if( $ctx.stash.metadata.modelObjectKey ) #set( $key = $ctx.stash.metadata.modelObjectKey ) #else @@ -12643,6 +12682,7 @@ $util.toJson($GetRequest) \\"version\\": \\"2018-05-29\\", \\"operation\\": \\"GetItem\\" } ) +$util.unauthorized() #if( $ctx.stash.metadata.modelObjectKey ) #set( $key = $ctx.stash.metadata.modelObjectKey ) #else @@ -12671,6 +12711,7 @@ $util.qr($ctx.stash.metadata.put(\\"modelObjectKey\\", { \\"version\\": \\"2018-05-29\\", \\"operation\\": \\"GetItem\\" } ) +$util.unauthorized() #if( $ctx.stash.metadata.modelObjectKey ) #set( $key = $ctx.stash.metadata.modelObjectKey ) #else @@ -12693,6 +12734,7 @@ $util.toJson($GetRequest) \\"version\\": \\"2018-05-29\\", \\"operation\\": \\"GetItem\\" } ) +$util.unauthorized() #if( $ctx.stash.metadata.modelObjectKey ) #set( $key = $ctx.stash.metadata.modelObjectKey ) #else @@ -12715,6 +12757,7 @@ $util.toJson($GetRequest) \\"version\\": \\"2018-05-29\\", \\"operation\\": \\"GetItem\\" } ) +$util.unauthorized() #if( $ctx.stash.metadata.modelObjectKey ) #set( $key = $ctx.stash.metadata.modelObjectKey ) #else @@ -12737,6 +12780,7 @@ $util.toJson($GetRequest) \\"version\\": \\"2018-05-29\\", \\"operation\\": \\"GetItem\\" } ) +$util.unauthorized() #if( $ctx.stash.metadata.modelObjectKey ) #set( $key = $ctx.stash.metadata.modelObjectKey ) #else @@ -12766,6 +12810,7 @@ $util.qr($ctx.stash.metadata.put(\\"modelObjectKey\\", { \\"version\\": \\"2018-05-29\\", \\"operation\\": \\"GetItem\\" } ) +$util.unauthorized() #if( $ctx.stash.metadata.modelObjectKey ) #set( $key = $ctx.stash.metadata.modelObjectKey ) #else @@ -12795,6 +12840,7 @@ $util.qr($ctx.stash.metadata.put(\\"modelObjectKey\\", { \\"version\\": \\"2018-05-29\\", \\"operation\\": \\"GetItem\\" } ) +$util.unauthorized() #if( $ctx.stash.metadata.modelObjectKey ) #set( $key = $ctx.stash.metadata.modelObjectKey ) #else @@ -12824,6 +12870,7 @@ $util.qr($ctx.stash.metadata.put(\\"modelObjectKey\\", { \\"version\\": \\"2018-05-29\\", \\"operation\\": \\"GetItem\\" } ) +$util.unauthorized() #if( $ctx.stash.metadata.modelObjectKey ) #set( $key = $ctx.stash.metadata.modelObjectKey ) #else @@ -12909,6 +12956,7 @@ $util.qr($ctx.stash.put(\\"modelQueryExpression\\", $modelQueryExpression)) \\"version\\": \\"2018-05-29\\", \\"limit\\": $limit } ) +$util.unauthorized() #if( $context.args.nextToken ) #set( $ListRequest.nextToken = $context.args.nextToken ) #end @@ -12950,6 +12998,7 @@ $util.toJson($ListRequest) \\"version\\": \\"2018-05-29\\", \\"limit\\": $limit } ) +$util.unauthorized() #if( $context.args.nextToken ) #set( $ListRequest.nextToken = $context.args.nextToken ) #end @@ -12991,6 +13040,7 @@ $util.toJson($ListRequest) \\"version\\": \\"2018-05-29\\", \\"limit\\": $limit } ) +$util.unauthorized() #if( $context.args.nextToken ) #set( $ListRequest.nextToken = $context.args.nextToken ) #end @@ -13032,6 +13082,7 @@ $util.toJson($ListRequest) \\"version\\": \\"2018-05-29\\", \\"limit\\": $limit } ) +$util.unauthorized() #if( $context.args.nextToken ) #set( $ListRequest.nextToken = $context.args.nextToken ) #end @@ -13073,6 +13124,7 @@ $util.toJson($ListRequest) \\"version\\": \\"2018-05-29\\", \\"limit\\": $limit } ) +$util.unauthorized() #if( $context.args.nextToken ) #set( $ListRequest.nextToken = $context.args.nextToken ) #end @@ -13114,6 +13166,7 @@ $util.toJson($ListRequest) \\"version\\": \\"2018-05-29\\", \\"limit\\": $limit } ) +$util.unauthorized() #if( $context.args.nextToken ) #set( $ListRequest.nextToken = $context.args.nextToken ) #end @@ -13174,6 +13227,7 @@ $util.qr($ctx.stash.put(\\"modelQueryExpression\\", $modelQueryExpression)) \\"version\\": \\"2018-05-29\\", \\"limit\\": $limit } ) +$util.unauthorized() #if( $context.args.nextToken ) #set( $ListRequest.nextToken = $context.args.nextToken ) #end @@ -13323,6 +13377,7 @@ $util.qr($ctx.stash.put(\\"modelQueryExpression\\", $modelQueryExpression)) \\"version\\": \\"2018-05-29\\", \\"limit\\": $limit } ) +$util.unauthorized() #if( $context.args.nextToken ) #set( $ListRequest.nextToken = $context.args.nextToken ) #end @@ -13364,6 +13419,7 @@ $util.toJson($ListRequest) \\"version\\": \\"2018-05-29\\", \\"limit\\": $limit } ) +$util.unauthorized() #if( $context.args.nextToken ) #set( $ListRequest.nextToken = $context.args.nextToken ) #end @@ -13467,6 +13523,7 @@ $util.qr($ctx.stash.put(\\"modelQueryExpression\\", $modelQueryExpression)) \\"version\\": \\"2018-05-29\\", \\"limit\\": $limit } ) +$util.unauthorized() #if( $context.args.nextToken ) #set( $ListRequest.nextToken = $context.args.nextToken ) #end @@ -13616,6 +13673,7 @@ $util.qr($ctx.stash.put(\\"modelQueryExpression\\", $modelQueryExpression)) \\"version\\": \\"2018-05-29\\", \\"limit\\": $limit } ) +$util.unauthorized() #if( $context.args.nextToken ) #set( $ListRequest.nextToken = $context.args.nextToken ) #end diff --git a/packages/amplify-graphql-searchable-transformer/src/__tests__/__snapshots__/amplify-graphql-searchable-transformer.tests.ts.snap b/packages/amplify-graphql-searchable-transformer/src/__tests__/__snapshots__/amplify-graphql-searchable-transformer.tests.ts.snap index 4f2f780d9da..642501f276c 100644 --- a/packages/amplify-graphql-searchable-transformer/src/__tests__/__snapshots__/amplify-graphql-searchable-transformer.tests.ts.snap +++ b/packages/amplify-graphql-searchable-transformer/src/__tests__/__snapshots__/amplify-graphql-searchable-transformer.tests.ts.snap @@ -630,6 +630,7 @@ $util.toJson({ $util.qr($mergedValues.putAll($util.defaultIfNull($ctx.args.input, {}))) ## set the typename ** $util.qr($mergedValues.put(\\"__typename\\", \\"Post\\")) +$util.unauthorized() #set( $PutObject = { \\"version\\": \\"2018-05-29\\", \\"operation\\": \\"PutItem\\", @@ -700,6 +701,7 @@ $util.toJson($PutObject) \\"version\\": \\"2018-05-29\\", \\"operation\\": \\"DeleteItem\\" } ) +$util.unauthorized() #if( $ctx.stash.metadata.modelObjectKey ) #set( $Key = $ctx.stash.metadata.modelObjectKey ) #else @@ -780,6 +782,7 @@ $util.qr($mergedValues.putAll($util.defaultIfNull($ctx.args.input, {}))) #set( $expSet = {} ) #set( $expAdd = {} ) #set( $expRemove = [] ) +$util.unauthorized() #if( $ctx.stash.metadata.modelObjectKey ) #set( $Key = $ctx.stash.metadata.modelObjectKey ) #else @@ -909,6 +912,7 @@ $util.toJson($UpdateItem) \\"version\\": \\"2018-05-29\\", \\"operation\\": \\"GetItem\\" } ) +$util.unauthorized() #if( $ctx.stash.metadata.modelObjectKey ) #set( $key = $ctx.stash.metadata.modelObjectKey ) #else @@ -932,6 +936,7 @@ $util.toJson($GetRequest) \\"version\\": \\"2018-05-29\\", \\"limit\\": $limit } ) +$util.unauthorized() #if( $context.args.nextToken ) #set( $ListRequest.nextToken = $context.args.nextToken ) #end diff --git a/packages/amplify-graphql-transformer-core/package.json b/packages/amplify-graphql-transformer-core/package.json index 3a36dfe7c73..89cf2f07612 100644 --- a/packages/amplify-graphql-transformer-core/package.json +++ b/packages/amplify-graphql-transformer-core/package.json @@ -52,6 +52,7 @@ "@aws-cdk/custom-resources": "~1.119.0", "@aws-cdk/cx-api": "~1.119.0", "@aws-cdk/region-info": "~1.119.0", + "amplify-cli-core": "1.26.0", "change-case": "^4.1.1", "constructs": "^3.3.125", "deep-diff": "^1.0.2", diff --git a/packages/amplify-graphql-transformer-core/src/graphql-api.ts b/packages/amplify-graphql-transformer-core/src/graphql-api.ts index 71d9fa52dc8..2b16a71e34a 100644 --- a/packages/amplify-graphql-transformer-core/src/graphql-api.ts +++ b/packages/amplify-graphql-transformer-core/src/graphql-api.ts @@ -17,6 +17,7 @@ import { Grant, IGrantable, ManagedPolicy, Role, ServicePrincipal } from '@aws-c import { CfnResource, Construct, Duration, Stack } from '@aws-cdk/core'; import { TransformerSchema } from './cdk-compat/schema-asset'; import { DefaultTransformHost } from './transform-host'; +import { stateManager } from 'amplify-cli-core'; export interface GraphqlApiProps { /** @@ -125,7 +126,7 @@ export class GraphQLApi extends GraphqlApiBase implements GraphQLAPIProvider { * The TransformHost object provides resource creation utilities in AWS * such as a LambdaDataSource or a DynamoDBDataSource */ - public readonly host: TransformHostProvider + public readonly host: TransformHostProvider; /** * the ARN of the API @@ -161,6 +162,11 @@ export class GraphQLApi extends GraphqlApiBase implements GraphQLAPIProvider { */ public readonly apiKey?: string; + /** + * Global Sandbox Mode for GraphQL API + */ + public readonly globalSandboxModeEnabled?: boolean; + private schemaResource: CfnGraphQLSchema; private api: CfnGraphQLApi; private apiKeyResource?: CfnApiKey; @@ -207,13 +213,28 @@ export class GraphQLApi extends GraphqlApiBase implements GraphQLAPIProvider { this.apiKey = this.apiKeyResource.attrApiKey; } + const hasApiKey = modes.some(mode => mode.authorizationType === AuthorizationType.API_KEY); + const hasMetaFile = stateManager.metaFileExists(); + + if (hasApiKey && hasMetaFile) { + const apiConfig = stateManager.getMeta()?.api; + const { envName } = stateManager.getLocalEnvInfo(); + let appSyncApi: any; + + Object.keys(apiConfig).forEach(k => { + if (apiConfig[k]['service'] === 'AppSync') appSyncApi = apiConfig[k]; + }); + const { globalSandboxModeConfig } = appSyncApi?.output || {}; + + this.globalSandboxModeEnabled = globalSandboxModeConfig && globalSandboxModeConfig[envName]?.enabled; + } + if (props.host) { this.host = props.host; this.host.setAPI(this); - } - else { + } else { this.host = new DefaultTransformHost({ - api: this + api: this, }); } } diff --git a/yarn.lock b/yarn.lock index 93de5ce179d..5acb2a5fcea 100644 --- a/yarn.lock +++ b/yarn.lock @@ -6654,6 +6654,28 @@ amdefine@>=0.0.4: resolved "https://registry.yarnpkg.com/amdefine/-/amdefine-1.0.1.tgz#4a5282ac164729e93619bcfd3ad151f817ce91f5" integrity sha1-SlKCrBZHKek2Gbz9OtFR+BfOkfU= +amplify-cli-core@1.26.0: + version "1.26.0" + resolved "https://registry.yarnpkg.com/amplify-cli-core/-/amplify-cli-core-1.26.0.tgz#de4579b73c97f1a020e4fc404460a41a51ad4a48" + integrity sha512-XG21+eAvpaDfdGFvlmfqDL3DdsZDp2ds7QgLZ5deSHWW0FtZqdXdfd7kW0ehZWvTj2ILyjroWARa6YkKFb79FA== + dependencies: + ajv "^6.12.3" + amplify-cli-logger "1.1.0" + ci-info "^2.0.0" + cloudform-types "^4.2.0" + dotenv "^8.2.0" + folder-hash "^4.0.1" + fs-extra "^8.1.0" + globby "^11.0.3" + hjson "^3.2.1" + js-yaml "^4.0.0" + lodash "^4.17.21" + node-fetch "^2.6.1" + open "^7.3.1" + proxy-agent "^4.0.1" + semver "^7.3.5" + which "^2.0.2" + amplify-codegen@^2.23.1: version "2.26.2" resolved "https://registry.yarnpkg.com/amplify-codegen/-/amplify-codegen-2.26.2.tgz#f5837dae2a15eaee214fe7eb318aa577a1f7e198" From 42349a12559b36f372bff6f6e18607b999f91226 Mon Sep 17 00:00:00 2001 From: Danielle Adams Date: Mon, 30 Aug 2021 10:20:55 -0400 Subject: [PATCH 5/9] test(amplify-category-api): add unit tests for provider utils --- .../prompt-to-add-api-key.test.ts | 48 +++++++++++++++++++ .../utils/global-sandbox-mode.test.ts | 21 ++++++++ packages/amplify-category-api/src/index.ts | 2 +- ...dd-api-key.ts => prompt-to-add-api-key.ts} | 9 ++-- .../utils/global-sandbox-mode.ts | 4 +- ...key.test.ts => get-api-key-config.test.ts} | 2 +- .../{api-key.ts => get-api-key-config.ts} | 0 .../amplify-helpers/push-resources.ts | 2 +- .../show-global-sandbox-mode-warning.ts | 2 +- .../src/__tests__/model-transformer.test.ts | 3 +- 10 files changed, 82 insertions(+), 11 deletions(-) create mode 100644 packages/amplify-category-api/src/__tests__/provider-utils/awscloudformation/prompt-to-add-api-key.test.ts create mode 100644 packages/amplify-category-api/src/__tests__/provider-utils/awscloudformation/utils/global-sandbox-mode.test.ts rename packages/amplify-category-api/src/provider-utils/awscloudformation/{utils/service-walkthrough-to-add-api-key.ts => prompt-to-add-api-key.ts} (69%) rename packages/amplify-cli/src/__tests__/extensions/amplify-helpers/{api-key.test.ts => get-api-key-config.test.ts} (96%) rename packages/amplify-cli/src/extensions/amplify-helpers/{api-key.ts => get-api-key-config.ts} (100%) diff --git a/packages/amplify-category-api/src/__tests__/provider-utils/awscloudformation/prompt-to-add-api-key.test.ts b/packages/amplify-category-api/src/__tests__/provider-utils/awscloudformation/prompt-to-add-api-key.test.ts new file mode 100644 index 00000000000..5af42fccdf3 --- /dev/null +++ b/packages/amplify-category-api/src/__tests__/provider-utils/awscloudformation/prompt-to-add-api-key.test.ts @@ -0,0 +1,48 @@ +import chalk from 'chalk'; +import { $TSContext } from 'amplify-cli-core'; +import { promptToAddApiKey } from '../../../provider-utils/awscloudformation/prompt-to-add-api-key'; + +describe('prompt to add Api Key', () => { + beforeEach(() => { + jest.mock('../../../provider-utils/awscloudformation/service-walkthroughs/appSync-walkthrough', () => ({ + askApiKeyQuestions: jest.fn(), + })); + + jest.mock('../../../provider-utils/awscloudformation/cfn-api-artifact-handler', () => ({ + getCfnApiArtifactHandler() { + return { updateArtifactsWithoutCompile: jest.fn() }; + }, + })); + }); + + it('runs through expected user flow: print info, update files', () => { + const envName = 'envone'; + const ctx = { + amplify: { + getEnvInfo() { + return { envName }; + }, + }, + print: { + info: jest.fn(), + }, + prompt: { + confirm: jest.fn(() => true), + }, + } as unknown as $TSContext; + + jest.spyOn(ctx.print, 'info'); + jest.spyOn(ctx.prompt, 'confirm'); + + promptToAddApiKey(ctx); + + expect(ctx.print.info).toHaveBeenCalledWith(` +⚠️ WARNING: Global Sandbox Mode has been enabled, which requires a valid API key. If +you'd like to disable, remove ${chalk.green('"type AMPLIFY_GLOBAL @allow_public_data_access_with_api_key"')} +from your GraphQL schema and run 'amplify push' again. If you'd like to proceed with +sandbox mode disabled in '${ctx.amplify.getEnvInfo().envName}', do not create an API Key. +`); + + expect(ctx.prompt.confirm).toHaveBeenCalledWith('Would you like to create an API Key?', true); + }); +}); diff --git a/packages/amplify-category-api/src/__tests__/provider-utils/awscloudformation/utils/global-sandbox-mode.test.ts b/packages/amplify-category-api/src/__tests__/provider-utils/awscloudformation/utils/global-sandbox-mode.test.ts new file mode 100644 index 00000000000..a895da7f667 --- /dev/null +++ b/packages/amplify-category-api/src/__tests__/provider-utils/awscloudformation/utils/global-sandbox-mode.test.ts @@ -0,0 +1,21 @@ +import { defineGlobalSandboxMode } from '../../../../provider-utils/awscloudformation/utils/global-sandbox-mode'; +import { $TSContext } from 'amplify-cli-core'; + +describe('global sandbox mode GraphQL directive', () => { + it('returns AMPLIFY_DIRECTIVE type with code comment, directive, and env name', () => { + const envName = 'envone'; + const ctx = <$TSContext>{ + amplify: { + getEnvInfo() { + return { envName }; + }, + }, + }; + + expect(defineGlobalSandboxMode(ctx)) + .toBe(`# This allows public create, read, update, and delete access for a limited time to all models via API Key. +# To configure PRODUCTION-READY authorization rules, review: https://docs.amplify.aws/cli/graphql-transformer/auth +type AMPLIFY_GLOBAL @allow_public_data_access_with_api_key(in: \"${envName}\") # FOR TESTING ONLY!\n +`); + }); +}); diff --git a/packages/amplify-category-api/src/index.ts b/packages/amplify-category-api/src/index.ts index e14947c1021..85cbadb761e 100644 --- a/packages/amplify-category-api/src/index.ts +++ b/packages/amplify-category-api/src/index.ts @@ -15,7 +15,7 @@ export { processDockerConfig, } from './provider-utils/awscloudformation/utils/containers-artifacts'; export { getContainers } from './provider-utils/awscloudformation/docker-compose'; -export { promptToAddApiKey } from './provider-utils/awscloudformation/utils/service-walkthrough-to-add-api-key'; +export { promptToAddApiKey } from './provider-utils/awscloudformation/prompt-to-add-api-key'; const category = 'api'; diff --git a/packages/amplify-category-api/src/provider-utils/awscloudformation/utils/service-walkthrough-to-add-api-key.ts b/packages/amplify-category-api/src/provider-utils/awscloudformation/prompt-to-add-api-key.ts similarity index 69% rename from packages/amplify-category-api/src/provider-utils/awscloudformation/utils/service-walkthrough-to-add-api-key.ts rename to packages/amplify-category-api/src/provider-utils/awscloudformation/prompt-to-add-api-key.ts index 968e7e27f75..1168b24a9d2 100644 --- a/packages/amplify-category-api/src/provider-utils/awscloudformation/utils/service-walkthrough-to-add-api-key.ts +++ b/packages/amplify-category-api/src/provider-utils/awscloudformation/prompt-to-add-api-key.ts @@ -1,9 +1,10 @@ import chalk from 'chalk'; -import { askApiKeyQuestions } from '../service-walkthroughs/appSync-walkthrough'; -import { authConfigToAppSyncAuthType } from '../utils/auth-config-to-app-sync-auth-type-bi-di-mapper'; -import { getCfnApiArtifactHandler } from '../cfn-api-artifact-handler'; +import { askApiKeyQuestions } from './service-walkthroughs/appSync-walkthrough'; +import { authConfigToAppSyncAuthType } from './utils/auth-config-to-app-sync-auth-type-bi-di-mapper'; +import { getCfnApiArtifactHandler } from './cfn-api-artifact-handler'; +import { $TSContext } from 'amplify-cli-core'; -export async function promptToAddApiKey(context): Promise { +export async function promptToAddApiKey(context: $TSContext): Promise { context.print.info(` ⚠️ WARNING: Global Sandbox Mode has been enabled, which requires a valid API key. If you'd like to disable, remove ${chalk.green('"type AMPLIFY_GLOBAL @allow_public_data_access_with_api_key"')} diff --git a/packages/amplify-category-api/src/provider-utils/awscloudformation/utils/global-sandbox-mode.ts b/packages/amplify-category-api/src/provider-utils/awscloudformation/utils/global-sandbox-mode.ts index 44aa0ec4793..27fc26f1f30 100644 --- a/packages/amplify-category-api/src/provider-utils/awscloudformation/utils/global-sandbox-mode.ts +++ b/packages/amplify-category-api/src/provider-utils/awscloudformation/utils/global-sandbox-mode.ts @@ -1,4 +1,6 @@ -export function defineGlobalSandboxMode(context: any): string { +import { $TSContext } from 'amplify-cli-core'; + +export function defineGlobalSandboxMode(context: $TSContext): string { const envName = context.amplify.getEnvInfo().envName; return `# This allows public create, read, update, and delete access for a limited time to all models via API Key. diff --git a/packages/amplify-cli/src/__tests__/extensions/amplify-helpers/api-key.test.ts b/packages/amplify-cli/src/__tests__/extensions/amplify-helpers/get-api-key-config.test.ts similarity index 96% rename from packages/amplify-cli/src/__tests__/extensions/amplify-helpers/api-key.test.ts rename to packages/amplify-cli/src/__tests__/extensions/amplify-helpers/get-api-key-config.test.ts index afb2d5deb61..d8251485a73 100644 --- a/packages/amplify-cli/src/__tests__/extensions/amplify-helpers/api-key.test.ts +++ b/packages/amplify-cli/src/__tests__/extensions/amplify-helpers/get-api-key-config.test.ts @@ -1,5 +1,5 @@ import fs from 'fs'; -import { getAppSyncApiConfig, getApiKeyConfig, apiKeyIsActive, hasApiKey } from '../../../extensions/amplify-helpers/api-key'; +import { getAppSyncApiConfig, getApiKeyConfig, apiKeyIsActive, hasApiKey } from '../../../extensions/amplify-helpers/get-api-key-config'; import { stateManager } from 'amplify-cli-core'; jest.mock('amplify-cli-core', () => { diff --git a/packages/amplify-cli/src/extensions/amplify-helpers/api-key.ts b/packages/amplify-cli/src/extensions/amplify-helpers/get-api-key-config.ts similarity index 100% rename from packages/amplify-cli/src/extensions/amplify-helpers/api-key.ts rename to packages/amplify-cli/src/extensions/amplify-helpers/get-api-key-config.ts diff --git a/packages/amplify-cli/src/extensions/amplify-helpers/push-resources.ts b/packages/amplify-cli/src/extensions/amplify-helpers/push-resources.ts index a06e5d50f95..9e3bba53885 100644 --- a/packages/amplify-cli/src/extensions/amplify-helpers/push-resources.ts +++ b/packages/amplify-cli/src/extensions/amplify-helpers/push-resources.ts @@ -5,7 +5,7 @@ import { initializeEnv } from '../../initialize-env'; import { getProviderPlugins } from './get-provider-plugins'; import { getEnvInfo } from './get-env-info'; import { globalSandboxModeEnabled, showGlobalSandboxModeWarning } from './show-global-sandbox-mode-warning'; -import { apiKeyIsActive, hasApiKey } from './api-key'; +import { apiKeyIsActive, hasApiKey } from './get-api-key-config'; import { EnvironmentDoesNotExistError, exitOnNextTick, stateManager, $TSAny, $TSContext } from 'amplify-cli-core'; import { promptToAddApiKey } from 'amplify-category-api'; diff --git a/packages/amplify-cli/src/extensions/amplify-helpers/show-global-sandbox-mode-warning.ts b/packages/amplify-cli/src/extensions/amplify-helpers/show-global-sandbox-mode-warning.ts index 5456bd062bd..439f11db60b 100644 --- a/packages/amplify-cli/src/extensions/amplify-helpers/show-global-sandbox-mode-warning.ts +++ b/packages/amplify-cli/src/extensions/amplify-helpers/show-global-sandbox-mode-warning.ts @@ -1,6 +1,6 @@ import chalk from 'chalk'; import { $TSContext } from 'amplify-cli-core'; -import { getAppSyncApiConfig, getApiKeyConfig } from './api-key'; +import { getAppSyncApiConfig, getApiKeyConfig } from './get-api-key-config'; export function globalSandboxModeEnabled(context: $TSContext): boolean { const appSyncApi = getAppSyncApiConfig(); diff --git a/packages/amplify-graphql-model-transformer/src/__tests__/model-transformer.test.ts b/packages/amplify-graphql-model-transformer/src/__tests__/model-transformer.test.ts index 4ddf9d7d8e6..6293dc05b6a 100644 --- a/packages/amplify-graphql-model-transformer/src/__tests__/model-transformer.test.ts +++ b/packages/amplify-graphql-model-transformer/src/__tests__/model-transformer.test.ts @@ -880,7 +880,7 @@ describe('ModelTransformer: ', () => { validateModelSchema(parse(out.schema)); }); - it.skip('should support global sandbox mode', () => { + it('should support global sandbox mode', () => { const validSchema = ` type AMPLIFY_GLOBAL @allow_public_data_access_with_api_key(in: \"dev\") @@ -897,7 +897,6 @@ describe('ModelTransformer: ', () => { const out = transformer.transform(validSchema); expect(out).toBeDefined(); - validateModelSchema(parse(out.schema)); parse(out.schema); }); }); From 74771aa62ce8a9683937b11376c5e75f308d04b2 Mon Sep 17 00:00:00 2001 From: Danielle Adams Date: Mon, 30 Aug 2021 11:28:08 -0400 Subject: [PATCH 6/9] test(amplify-e2e-tests): add e2e test for generating sandbox mode --- .circleci/config.yml | 190 ++++++++++-------- .../schemas/model_with_sandbox_mode.graphql | 6 + .../src/__tests__/sandbox-mode.test.ts | 41 ++++ 3 files changed, 157 insertions(+), 80 deletions(-) create mode 100644 packages/amplify-e2e-tests/schemas/model_with_sandbox_mode.graphql create mode 100644 packages/amplify-e2e-tests/src/__tests__/sandbox-mode.test.ts diff --git a/.circleci/config.yml b/.circleci/config.yml index b0610449790..96db0accb3f 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -1171,6 +1171,14 @@ jobs: environment: TEST_SUITE: src/__tests__/schema-iterative-update-locking.test.ts CLI_REGION: us-east-2 + sandbox-mode-amplify_e2e_tests: + working_directory: ~/repo + docker: *ref_1 + resource_class: large + steps: *ref_5 + environment: + TEST_SUITE: src/__tests__/sandbox-mode.test.ts + CLI_REGION: us-west-2 s3-sse-amplify_e2e_tests: working_directory: ~/repo docker: *ref_1 @@ -1178,7 +1186,7 @@ jobs: steps: *ref_5 environment: TEST_SUITE: src/__tests__/s3-sse.test.ts - CLI_REGION: us-west-2 + CLI_REGION: eu-west-2 pull-amplify_e2e_tests: working_directory: ~/repo docker: *ref_1 @@ -1186,7 +1194,7 @@ jobs: steps: *ref_5 environment: TEST_SUITE: src/__tests__/pull.test.ts - CLI_REGION: eu-west-2 + CLI_REGION: eu-central-1 migration-node-function-amplify_e2e_tests: working_directory: ~/repo docker: *ref_1 @@ -1194,7 +1202,7 @@ jobs: steps: *ref_5 environment: TEST_SUITE: src/__tests__/migration/node.function.test.ts - CLI_REGION: eu-central-1 + CLI_REGION: ap-northeast-1 layer-2-amplify_e2e_tests: working_directory: ~/repo docker: *ref_1 @@ -1202,7 +1210,7 @@ jobs: steps: *ref_5 environment: TEST_SUITE: src/__tests__/layer-2.test.ts - CLI_REGION: ap-northeast-1 + CLI_REGION: ap-southeast-1 iam-permissions-boundary-amplify_e2e_tests: working_directory: ~/repo docker: *ref_1 @@ -1210,7 +1218,7 @@ jobs: steps: *ref_5 environment: TEST_SUITE: src/__tests__/iam-permissions-boundary.test.ts - CLI_REGION: ap-southeast-1 + CLI_REGION: ap-southeast-2 function_7-amplify_e2e_tests: working_directory: ~/repo docker: *ref_1 @@ -1218,7 +1226,7 @@ jobs: steps: *ref_5 environment: TEST_SUITE: src/__tests__/function_7.test.ts - CLI_REGION: ap-southeast-2 + CLI_REGION: us-east-2 function_6-amplify_e2e_tests: working_directory: ~/repo docker: *ref_1 @@ -1226,7 +1234,7 @@ jobs: steps: *ref_5 environment: TEST_SUITE: src/__tests__/function_6.test.ts - CLI_REGION: us-east-2 + CLI_REGION: us-west-2 function_5-amplify_e2e_tests: working_directory: ~/repo docker: *ref_1 @@ -1234,7 +1242,7 @@ jobs: steps: *ref_5 environment: TEST_SUITE: src/__tests__/function_5.test.ts - CLI_REGION: us-west-2 + CLI_REGION: eu-west-2 frontend_config_drift-amplify_e2e_tests: working_directory: ~/repo docker: *ref_1 @@ -1242,7 +1250,7 @@ jobs: steps: *ref_5 environment: TEST_SUITE: src/__tests__/frontend_config_drift.test.ts - CLI_REGION: eu-west-2 + CLI_REGION: eu-central-1 container-hosting-amplify_e2e_tests: working_directory: ~/repo docker: *ref_1 @@ -1250,7 +1258,7 @@ jobs: steps: *ref_5 environment: TEST_SUITE: src/__tests__/container-hosting.test.ts - CLI_REGION: eu-central-1 + CLI_REGION: ap-northeast-1 configure-project-amplify_e2e_tests: working_directory: ~/repo docker: *ref_1 @@ -1258,7 +1266,7 @@ jobs: steps: *ref_5 environment: TEST_SUITE: src/__tests__/configure-project.test.ts - CLI_REGION: ap-northeast-1 + CLI_REGION: ap-southeast-1 auth_6-amplify_e2e_tests: working_directory: ~/repo docker: *ref_1 @@ -1266,7 +1274,7 @@ jobs: steps: *ref_5 environment: TEST_SUITE: src/__tests__/auth_6.test.ts - CLI_REGION: ap-southeast-1 + CLI_REGION: ap-southeast-2 api_4-amplify_e2e_tests: working_directory: ~/repo docker: *ref_1 @@ -1274,7 +1282,7 @@ jobs: steps: *ref_5 environment: TEST_SUITE: src/__tests__/api_4.test.ts - CLI_REGION: ap-southeast-2 + CLI_REGION: us-east-2 schema-iterative-update-4-amplify_e2e_tests_pkg_linux: working_directory: ~/repo docker: *ref_1 @@ -1915,6 +1923,16 @@ jobs: TEST_SUITE: src/__tests__/schema-iterative-update-locking.test.ts CLI_REGION: us-east-2 steps: *ref_6 + sandbox-mode-amplify_e2e_tests_pkg_linux: + working_directory: ~/repo + docker: *ref_1 + resource_class: large + environment: + AMPLIFY_DIR: /home/circleci/repo/out + AMPLIFY_PATH: /home/circleci/repo/out/amplify-pkg-linux + TEST_SUITE: src/__tests__/sandbox-mode.test.ts + CLI_REGION: us-west-2 + steps: *ref_6 s3-sse-amplify_e2e_tests_pkg_linux: working_directory: ~/repo docker: *ref_1 @@ -1923,7 +1941,7 @@ jobs: AMPLIFY_DIR: /home/circleci/repo/out AMPLIFY_PATH: /home/circleci/repo/out/amplify-pkg-linux TEST_SUITE: src/__tests__/s3-sse.test.ts - CLI_REGION: us-west-2 + CLI_REGION: eu-west-2 steps: *ref_6 pull-amplify_e2e_tests_pkg_linux: working_directory: ~/repo @@ -1933,7 +1951,7 @@ jobs: AMPLIFY_DIR: /home/circleci/repo/out AMPLIFY_PATH: /home/circleci/repo/out/amplify-pkg-linux TEST_SUITE: src/__tests__/pull.test.ts - CLI_REGION: eu-west-2 + CLI_REGION: eu-central-1 steps: *ref_6 migration-node-function-amplify_e2e_tests_pkg_linux: working_directory: ~/repo @@ -1943,7 +1961,7 @@ jobs: AMPLIFY_DIR: /home/circleci/repo/out AMPLIFY_PATH: /home/circleci/repo/out/amplify-pkg-linux TEST_SUITE: src/__tests__/migration/node.function.test.ts - CLI_REGION: eu-central-1 + CLI_REGION: ap-northeast-1 steps: *ref_6 layer-2-amplify_e2e_tests_pkg_linux: working_directory: ~/repo @@ -1953,7 +1971,7 @@ jobs: AMPLIFY_DIR: /home/circleci/repo/out AMPLIFY_PATH: /home/circleci/repo/out/amplify-pkg-linux TEST_SUITE: src/__tests__/layer-2.test.ts - CLI_REGION: ap-northeast-1 + CLI_REGION: ap-southeast-1 steps: *ref_6 iam-permissions-boundary-amplify_e2e_tests_pkg_linux: working_directory: ~/repo @@ -1963,7 +1981,7 @@ jobs: AMPLIFY_DIR: /home/circleci/repo/out AMPLIFY_PATH: /home/circleci/repo/out/amplify-pkg-linux TEST_SUITE: src/__tests__/iam-permissions-boundary.test.ts - CLI_REGION: ap-southeast-1 + CLI_REGION: ap-southeast-2 steps: *ref_6 function_7-amplify_e2e_tests_pkg_linux: working_directory: ~/repo @@ -1973,7 +1991,7 @@ jobs: AMPLIFY_DIR: /home/circleci/repo/out AMPLIFY_PATH: /home/circleci/repo/out/amplify-pkg-linux TEST_SUITE: src/__tests__/function_7.test.ts - CLI_REGION: ap-southeast-2 + CLI_REGION: us-east-2 steps: *ref_6 function_6-amplify_e2e_tests_pkg_linux: working_directory: ~/repo @@ -1983,7 +2001,7 @@ jobs: AMPLIFY_DIR: /home/circleci/repo/out AMPLIFY_PATH: /home/circleci/repo/out/amplify-pkg-linux TEST_SUITE: src/__tests__/function_6.test.ts - CLI_REGION: us-east-2 + CLI_REGION: us-west-2 steps: *ref_6 function_5-amplify_e2e_tests_pkg_linux: working_directory: ~/repo @@ -1993,7 +2011,7 @@ jobs: AMPLIFY_DIR: /home/circleci/repo/out AMPLIFY_PATH: /home/circleci/repo/out/amplify-pkg-linux TEST_SUITE: src/__tests__/function_5.test.ts - CLI_REGION: us-west-2 + CLI_REGION: eu-west-2 steps: *ref_6 frontend_config_drift-amplify_e2e_tests_pkg_linux: working_directory: ~/repo @@ -2003,7 +2021,7 @@ jobs: AMPLIFY_DIR: /home/circleci/repo/out AMPLIFY_PATH: /home/circleci/repo/out/amplify-pkg-linux TEST_SUITE: src/__tests__/frontend_config_drift.test.ts - CLI_REGION: eu-west-2 + CLI_REGION: eu-central-1 steps: *ref_6 container-hosting-amplify_e2e_tests_pkg_linux: working_directory: ~/repo @@ -2013,7 +2031,7 @@ jobs: AMPLIFY_DIR: /home/circleci/repo/out AMPLIFY_PATH: /home/circleci/repo/out/amplify-pkg-linux TEST_SUITE: src/__tests__/container-hosting.test.ts - CLI_REGION: eu-central-1 + CLI_REGION: ap-northeast-1 steps: *ref_6 configure-project-amplify_e2e_tests_pkg_linux: working_directory: ~/repo @@ -2023,7 +2041,7 @@ jobs: AMPLIFY_DIR: /home/circleci/repo/out AMPLIFY_PATH: /home/circleci/repo/out/amplify-pkg-linux TEST_SUITE: src/__tests__/configure-project.test.ts - CLI_REGION: ap-northeast-1 + CLI_REGION: ap-southeast-1 steps: *ref_6 auth_6-amplify_e2e_tests_pkg_linux: working_directory: ~/repo @@ -2033,7 +2051,7 @@ jobs: AMPLIFY_DIR: /home/circleci/repo/out AMPLIFY_PATH: /home/circleci/repo/out/amplify-pkg-linux TEST_SUITE: src/__tests__/auth_6.test.ts - CLI_REGION: ap-southeast-1 + CLI_REGION: ap-southeast-2 steps: *ref_6 api_4-amplify_e2e_tests_pkg_linux: working_directory: ~/repo @@ -2043,7 +2061,7 @@ jobs: AMPLIFY_DIR: /home/circleci/repo/out AMPLIFY_PATH: /home/circleci/repo/out/amplify-pkg-linux TEST_SUITE: src/__tests__/api_4.test.ts - CLI_REGION: ap-southeast-2 + CLI_REGION: us-east-2 steps: *ref_6 workflows: version: 2 @@ -2147,64 +2165,64 @@ workflows: - /run-e2e\/*./ - done_with_node_e2e_tests: requires: - - analytics-amplify_e2e_tests - notifications-amplify_e2e_tests - schema-iterative-update-locking-amplify_e2e_tests - - function_6-amplify_e2e_tests + - function_7-amplify_e2e_tests + - api_4-amplify_e2e_tests - hosting-amplify_e2e_tests - tags-amplify_e2e_tests - - s3-sse-amplify_e2e_tests - - function_5-amplify_e2e_tests + - sandbox-mode-amplify_e2e_tests + - function_6-amplify_e2e_tests - amplify-app-amplify_e2e_tests - init-amplify_e2e_tests - - pull-amplify_e2e_tests - - frontend_config_drift-amplify_e2e_tests + - s3-sse-amplify_e2e_tests + - function_5-amplify_e2e_tests - schema-predictions-amplify_e2e_tests - amplify-configure-amplify_e2e_tests - - migration-node-function-amplify_e2e_tests - - container-hosting-amplify_e2e_tests + - pull-amplify_e2e_tests + - frontend_config_drift-amplify_e2e_tests - interactions-amplify_e2e_tests - datastore-modelgen-amplify_e2e_tests - - layer-2-amplify_e2e_tests - - configure-project-amplify_e2e_tests + - migration-node-function-amplify_e2e_tests + - container-hosting-amplify_e2e_tests - schema-data-access-patterns-amplify_e2e_tests - init-special-case-amplify_e2e_tests - - iam-permissions-boundary-amplify_e2e_tests - - auth_6-amplify_e2e_tests + - layer-2-amplify_e2e_tests + - configure-project-amplify_e2e_tests - schema-versioned-amplify_e2e_tests - plugin-amplify_e2e_tests - - function_7-amplify_e2e_tests - - api_4-amplify_e2e_tests + - iam-permissions-boundary-amplify_e2e_tests + - auth_6-amplify_e2e_tests - done_with_pkg_linux_e2e_tests: requires: - - analytics-amplify_e2e_tests_pkg_linux - notifications-amplify_e2e_tests_pkg_linux - schema-iterative-update-locking-amplify_e2e_tests_pkg_linux - - function_6-amplify_e2e_tests_pkg_linux + - function_7-amplify_e2e_tests_pkg_linux + - api_4-amplify_e2e_tests_pkg_linux - hosting-amplify_e2e_tests_pkg_linux - tags-amplify_e2e_tests_pkg_linux - - s3-sse-amplify_e2e_tests_pkg_linux - - function_5-amplify_e2e_tests_pkg_linux + - sandbox-mode-amplify_e2e_tests_pkg_linux + - function_6-amplify_e2e_tests_pkg_linux - amplify-app-amplify_e2e_tests_pkg_linux - init-amplify_e2e_tests_pkg_linux - - pull-amplify_e2e_tests_pkg_linux - - frontend_config_drift-amplify_e2e_tests_pkg_linux + - s3-sse-amplify_e2e_tests_pkg_linux + - function_5-amplify_e2e_tests_pkg_linux - schema-predictions-amplify_e2e_tests_pkg_linux - amplify-configure-amplify_e2e_tests_pkg_linux - - migration-node-function-amplify_e2e_tests_pkg_linux - - container-hosting-amplify_e2e_tests_pkg_linux + - pull-amplify_e2e_tests_pkg_linux + - frontend_config_drift-amplify_e2e_tests_pkg_linux - interactions-amplify_e2e_tests_pkg_linux - datastore-modelgen-amplify_e2e_tests_pkg_linux - - layer-2-amplify_e2e_tests_pkg_linux - - configure-project-amplify_e2e_tests_pkg_linux + - migration-node-function-amplify_e2e_tests_pkg_linux + - container-hosting-amplify_e2e_tests_pkg_linux - schema-data-access-patterns-amplify_e2e_tests_pkg_linux - init-special-case-amplify_e2e_tests_pkg_linux - - iam-permissions-boundary-amplify_e2e_tests_pkg_linux - - auth_6-amplify_e2e_tests_pkg_linux + - layer-2-amplify_e2e_tests_pkg_linux + - configure-project-amplify_e2e_tests_pkg_linux - schema-versioned-amplify_e2e_tests_pkg_linux - plugin-amplify_e2e_tests_pkg_linux - - function_7-amplify_e2e_tests_pkg_linux - - api_4-amplify_e2e_tests_pkg_linux + - iam-permissions-boundary-amplify_e2e_tests_pkg_linux + - auth_6-amplify_e2e_tests_pkg_linux - amplify_migration_tests_latest: context: - amplify-ecr-image-pull @@ -2420,12 +2438,18 @@ workflows: filters: *ref_10 requires: - function_2-amplify_e2e_tests - - function_6-amplify_e2e_tests: + - function_7-amplify_e2e_tests: context: *ref_8 post-steps: *ref_9 filters: *ref_10 requires: - schema-key-amplify_e2e_tests + - api_4-amplify_e2e_tests: + context: *ref_8 + post-steps: *ref_9 + filters: *ref_10 + requires: + - analytics-amplify_e2e_tests - api_2-amplify_e2e_tests: context: *ref_8 post-steps: *ref_9 @@ -2480,13 +2504,13 @@ workflows: filters: *ref_10 requires: - schema-auth-8-amplify_e2e_tests - - s3-sse-amplify_e2e_tests: + - sandbox-mode-amplify_e2e_tests: context: *ref_8 post-steps: *ref_9 filters: *ref_10 requires: - delete-amplify_e2e_tests - - function_5-amplify_e2e_tests: + - function_6-amplify_e2e_tests: context: *ref_8 post-steps: *ref_9 filters: *ref_10 @@ -2546,13 +2570,13 @@ workflows: filters: *ref_10 requires: - schema-auth-7-amplify_e2e_tests - - pull-amplify_e2e_tests: + - s3-sse-amplify_e2e_tests: context: *ref_8 post-steps: *ref_9 filters: *ref_10 requires: - schema-auth-3-amplify_e2e_tests - - frontend_config_drift-amplify_e2e_tests: + - function_5-amplify_e2e_tests: context: *ref_8 post-steps: *ref_9 filters: *ref_10 @@ -2612,13 +2636,13 @@ workflows: filters: *ref_10 requires: - auth_4-amplify_e2e_tests - - migration-node-function-amplify_e2e_tests: + - pull-amplify_e2e_tests: context: *ref_8 post-steps: *ref_9 filters: *ref_10 requires: - schema-iterative-update-1-amplify_e2e_tests - - container-hosting-amplify_e2e_tests: + - frontend_config_drift-amplify_e2e_tests: context: *ref_8 post-steps: *ref_9 filters: *ref_10 @@ -2678,13 +2702,13 @@ workflows: filters: *ref_10 requires: - migration-api-key-migration1-amplify_e2e_tests - - layer-2-amplify_e2e_tests: + - migration-node-function-amplify_e2e_tests: context: *ref_8 post-steps: *ref_9 filters: *ref_10 requires: - function_3-amplify_e2e_tests - - configure-project-amplify_e2e_tests: + - container-hosting-amplify_e2e_tests: context: *ref_8 post-steps: *ref_9 filters: *ref_10 @@ -2744,13 +2768,13 @@ workflows: filters: *ref_10 requires: - layer-amplify_e2e_tests - - iam-permissions-boundary-amplify_e2e_tests: + - layer-2-amplify_e2e_tests: context: *ref_8 post-steps: *ref_9 filters: *ref_10 requires: - auth_5-amplify_e2e_tests - - auth_6-amplify_e2e_tests: + - configure-project-amplify_e2e_tests: context: *ref_8 post-steps: *ref_9 filters: *ref_10 @@ -2810,13 +2834,13 @@ workflows: filters: *ref_10 requires: - auth_3-amplify_e2e_tests - - function_7-amplify_e2e_tests: + - iam-permissions-boundary-amplify_e2e_tests: context: *ref_8 post-steps: *ref_9 filters: *ref_10 requires: - auth_1-amplify_e2e_tests - - api_4-amplify_e2e_tests: + - auth_6-amplify_e2e_tests: context: *ref_8 post-steps: *ref_9 filters: *ref_10 @@ -2896,12 +2920,18 @@ workflows: filters: *ref_13 requires: - function_2-amplify_e2e_tests_pkg_linux - - function_6-amplify_e2e_tests_pkg_linux: + - function_7-amplify_e2e_tests_pkg_linux: context: *ref_11 post-steps: *ref_12 filters: *ref_13 requires: - schema-key-amplify_e2e_tests_pkg_linux + - api_4-amplify_e2e_tests_pkg_linux: + context: *ref_11 + post-steps: *ref_12 + filters: *ref_13 + requires: + - analytics-amplify_e2e_tests_pkg_linux - api_2-amplify_e2e_tests_pkg_linux: context: *ref_11 post-steps: *ref_12 @@ -2960,13 +2990,13 @@ workflows: filters: *ref_13 requires: - schema-auth-8-amplify_e2e_tests_pkg_linux - - s3-sse-amplify_e2e_tests_pkg_linux: + - sandbox-mode-amplify_e2e_tests_pkg_linux: context: *ref_11 post-steps: *ref_12 filters: *ref_13 requires: - delete-amplify_e2e_tests_pkg_linux - - function_5-amplify_e2e_tests_pkg_linux: + - function_6-amplify_e2e_tests_pkg_linux: context: *ref_11 post-steps: *ref_12 filters: *ref_13 @@ -3030,13 +3060,13 @@ workflows: filters: *ref_13 requires: - schema-auth-7-amplify_e2e_tests_pkg_linux - - pull-amplify_e2e_tests_pkg_linux: + - s3-sse-amplify_e2e_tests_pkg_linux: context: *ref_11 post-steps: *ref_12 filters: *ref_13 requires: - schema-auth-3-amplify_e2e_tests_pkg_linux - - frontend_config_drift-amplify_e2e_tests_pkg_linux: + - function_5-amplify_e2e_tests_pkg_linux: context: *ref_11 post-steps: *ref_12 filters: *ref_13 @@ -3100,13 +3130,13 @@ workflows: filters: *ref_13 requires: - auth_4-amplify_e2e_tests_pkg_linux - - migration-node-function-amplify_e2e_tests_pkg_linux: + - pull-amplify_e2e_tests_pkg_linux: context: *ref_11 post-steps: *ref_12 filters: *ref_13 requires: - schema-iterative-update-1-amplify_e2e_tests_pkg_linux - - container-hosting-amplify_e2e_tests_pkg_linux: + - frontend_config_drift-amplify_e2e_tests_pkg_linux: context: *ref_11 post-steps: *ref_12 filters: *ref_13 @@ -3170,13 +3200,13 @@ workflows: filters: *ref_13 requires: - migration-api-key-migration1-amplify_e2e_tests_pkg_linux - - layer-2-amplify_e2e_tests_pkg_linux: + - migration-node-function-amplify_e2e_tests_pkg_linux: context: *ref_11 post-steps: *ref_12 filters: *ref_13 requires: - function_3-amplify_e2e_tests_pkg_linux - - configure-project-amplify_e2e_tests_pkg_linux: + - container-hosting-amplify_e2e_tests_pkg_linux: context: *ref_11 post-steps: *ref_12 filters: *ref_13 @@ -3240,13 +3270,13 @@ workflows: filters: *ref_13 requires: - layer-amplify_e2e_tests_pkg_linux - - iam-permissions-boundary-amplify_e2e_tests_pkg_linux: + - layer-2-amplify_e2e_tests_pkg_linux: context: *ref_11 post-steps: *ref_12 filters: *ref_13 requires: - auth_5-amplify_e2e_tests_pkg_linux - - auth_6-amplify_e2e_tests_pkg_linux: + - configure-project-amplify_e2e_tests_pkg_linux: context: *ref_11 post-steps: *ref_12 filters: *ref_13 @@ -3310,13 +3340,13 @@ workflows: filters: *ref_13 requires: - auth_3-amplify_e2e_tests_pkg_linux - - function_7-amplify_e2e_tests_pkg_linux: + - iam-permissions-boundary-amplify_e2e_tests_pkg_linux: context: *ref_11 post-steps: *ref_12 filters: *ref_13 requires: - auth_1-amplify_e2e_tests_pkg_linux - - api_4-amplify_e2e_tests_pkg_linux: + - auth_6-amplify_e2e_tests_pkg_linux: context: *ref_11 post-steps: *ref_12 filters: *ref_13 diff --git a/packages/amplify-e2e-tests/schemas/model_with_sandbox_mode.graphql b/packages/amplify-e2e-tests/schemas/model_with_sandbox_mode.graphql new file mode 100644 index 00000000000..22c833e9c67 --- /dev/null +++ b/packages/amplify-e2e-tests/schemas/model_with_sandbox_mode.graphql @@ -0,0 +1,6 @@ +type AMPLIFY_GLOBAL @allow_public_data_access_with_api_key(in: "dev") + +type Todo @model { + id: ID! + content: String +} diff --git a/packages/amplify-e2e-tests/src/__tests__/sandbox-mode.test.ts b/packages/amplify-e2e-tests/src/__tests__/sandbox-mode.test.ts new file mode 100644 index 00000000000..2e3947521c4 --- /dev/null +++ b/packages/amplify-e2e-tests/src/__tests__/sandbox-mode.test.ts @@ -0,0 +1,41 @@ +import { + initJSProjectWithProfile, + deleteProject, + createNewProjectDir, + deleteProjectDir, + addApiWithSchema, + amplifyPush, + getProjectMeta, +} from 'amplify-e2e-core'; +import { testSchema } from '../schema-api-directives'; + +describe('api directives @allow_public_data_access_with_api_key', () => { + let projectDir: string; + const envName = 'dev'; + + beforeEach(async () => { + projectDir = await createNewProjectDir('model'); + await initJSProjectWithProfile(projectDir, { envName }); + }); + + afterEach(async () => { + await deleteProject(projectDir); + deleteProjectDir(projectDir); + }); + + it('schema and files generate with sandbox mode', async () => { + await addApiWithSchema(projectDir, 'model_with_sandbox_mode.graphql'); + await amplifyPush(projectDir); + + const meta = getProjectMeta(projectDir); + const { output } = meta.api.simplemodel; + const { authConfig, globalSandboxModeConfig } = output; + + expect(globalSandboxModeConfig[envName].enabled).toBe(true); + expect(authConfig.defaultAuthentication.authenticationType).toBe('API_KEY'); + expect(authConfig.defaultAuthentication.apiKeyConfig.apiKeyExpirationDate).toBeDefined(); + + const testresult = await testSchema(projectDir, 'model', 'generates'); + expect(testresult).toBeTruthy(); + }); +}); From 0b48a762a3763005a4cb9d1acbf1fc35c4aeccc6 Mon Sep 17 00:00:00 2001 From: Danielle Adams Date: Mon, 30 Aug 2021 12:14:43 -0400 Subject: [PATCH 7/9] test(graphql-model-transformer): add test for common module --- .../src/__tests__/resolvers/common.test.ts | 47 +++++++++++++++++++ .../src/__tests__/test-utils/helpers.ts | 1 - 2 files changed, 47 insertions(+), 1 deletion(-) create mode 100644 packages/amplify-graphql-model-transformer/src/__tests__/resolvers/common.test.ts diff --git a/packages/amplify-graphql-model-transformer/src/__tests__/resolvers/common.test.ts b/packages/amplify-graphql-model-transformer/src/__tests__/resolvers/common.test.ts new file mode 100644 index 00000000000..8584d1090c3 --- /dev/null +++ b/packages/amplify-graphql-model-transformer/src/__tests__/resolvers/common.test.ts @@ -0,0 +1,47 @@ +import { generateSandboxMode } from '../../resolvers'; +import { getInputType } from '../test-utils/helpers'; + +describe('generateSandboxMode', () => { + let ctx: any; + + beforeEach(() => { + ctx = { + resourceHelper: { + api: { globalSandboxModeEnabled: undefined }, + }, + }; + }); + + describe('when sandbox mode disabled', () => { + beforeEach(() => { + ctx.resourceHelper.api.globalSandboxModeEnabled = false; + }); + + it('generates unauthorized expression', () => { + const exp: any = generateSandboxMode(ctx); + const { value } = exp.expressions.find((e: any) => e.kind === 'Reference'); + + expect(value).toEqual('util.unauthorized'); + }); + }); + + describe('when sandbox mode enabled', () => { + beforeEach(() => { + ctx.resourceHelper.api.globalSandboxModeEnabled = true; + }); + + it('generates unauthorized expression for non API_KEY authorization type', () => { + const exp: any = generateSandboxMode(ctx); + const { kind, leftExpr, rightExpr } = exp.predicate; + const leftExprValue = leftExpr.expressions.find((e: any) => e.kind === 'Reference').value; + + expect(kind).toEqual('NotEquals'); + expect(leftExprValue).toEqual('util.authType'); + expect(rightExpr.value).toEqual('API_KEY'); + + const { value } = exp.expr.expressions.find((e: any) => e.kind === 'Reference'); + + expect(value).toEqual('util.unauthorized'); + }); + }); +}); diff --git a/packages/amplify-graphql-model-transformer/src/__tests__/test-utils/helpers.ts b/packages/amplify-graphql-model-transformer/src/__tests__/test-utils/helpers.ts index 16c22fdf1a7..0aaff22dd61 100644 --- a/packages/amplify-graphql-model-transformer/src/__tests__/test-utils/helpers.ts +++ b/packages/amplify-graphql-model-transformer/src/__tests__/test-utils/helpers.ts @@ -6,7 +6,6 @@ import { InputValueDefinitionNode, Kind, ObjectTypeDefinitionNode, - parse, TypeNode, } from 'graphql'; From 8c7d9b46e9f8491be84503f5f52c6ebd24b140f8 Mon Sep 17 00:00:00 2001 From: Danielle Adams Date: Mon, 30 Aug 2021 20:28:59 -0400 Subject: [PATCH 8/9] test(amplify-category-api): fix test for adding api key prompt --- .../prompt-to-add-api-key.test.ts | 30 +++++++++++-------- .../prompt-to-add-api-key.ts | 2 +- 2 files changed, 18 insertions(+), 14 deletions(-) diff --git a/packages/amplify-category-api/src/__tests__/provider-utils/awscloudformation/prompt-to-add-api-key.test.ts b/packages/amplify-category-api/src/__tests__/provider-utils/awscloudformation/prompt-to-add-api-key.test.ts index 5af42fccdf3..2a4803485c0 100644 --- a/packages/amplify-category-api/src/__tests__/provider-utils/awscloudformation/prompt-to-add-api-key.test.ts +++ b/packages/amplify-category-api/src/__tests__/provider-utils/awscloudformation/prompt-to-add-api-key.test.ts @@ -1,21 +1,21 @@ import chalk from 'chalk'; import { $TSContext } from 'amplify-cli-core'; import { promptToAddApiKey } from '../../../provider-utils/awscloudformation/prompt-to-add-api-key'; +import * as walkthrough from '../../../provider-utils/awscloudformation/service-walkthroughs/appSync-walkthrough'; +import * as cfnApiArtifactHandler from '../../../provider-utils/awscloudformation/cfn-api-artifact-handler'; -describe('prompt to add Api Key', () => { - beforeEach(() => { - jest.mock('../../../provider-utils/awscloudformation/service-walkthroughs/appSync-walkthrough', () => ({ - askApiKeyQuestions: jest.fn(), - })); +jest.mock('../../../provider-utils/awscloudformation/service-walkthroughs/appSync-walkthrough', () => ({ + askApiKeyQuestions: jest.fn(), +})); - jest.mock('../../../provider-utils/awscloudformation/cfn-api-artifact-handler', () => ({ - getCfnApiArtifactHandler() { - return { updateArtifactsWithoutCompile: jest.fn() }; - }, - })); - }); +jest.mock('../../../provider-utils/awscloudformation/cfn-api-artifact-handler', () => ({ + getCfnApiArtifactHandler: jest.fn(() => { + return { updateArtifactsWithoutCompile: jest.fn() }; + }), +})); - it('runs through expected user flow: print info, update files', () => { +describe('prompt to add Api Key', () => { + it('runs through expected user flow: print info, update files', async () => { const envName = 'envone'; const ctx = { amplify: { @@ -33,8 +33,10 @@ describe('prompt to add Api Key', () => { jest.spyOn(ctx.print, 'info'); jest.spyOn(ctx.prompt, 'confirm'); + jest.spyOn(walkthrough, 'askApiKeyQuestions'); + jest.spyOn(cfnApiArtifactHandler, 'getCfnApiArtifactHandler'); - promptToAddApiKey(ctx); + await promptToAddApiKey(ctx); expect(ctx.print.info).toHaveBeenCalledWith(` ⚠️ WARNING: Global Sandbox Mode has been enabled, which requires a valid API key. If @@ -44,5 +46,7 @@ sandbox mode disabled in '${ctx.amplify.getEnvInfo().envName}', do not create an `); expect(ctx.prompt.confirm).toHaveBeenCalledWith('Would you like to create an API Key?', true); + expect(walkthrough.askApiKeyQuestions).toHaveBeenCalledTimes(1); + expect(cfnApiArtifactHandler.getCfnApiArtifactHandler).toHaveBeenCalledTimes(1); }); }); diff --git a/packages/amplify-category-api/src/provider-utils/awscloudformation/prompt-to-add-api-key.ts b/packages/amplify-category-api/src/provider-utils/awscloudformation/prompt-to-add-api-key.ts index 1168b24a9d2..5bf1417409d 100644 --- a/packages/amplify-category-api/src/provider-utils/awscloudformation/prompt-to-add-api-key.ts +++ b/packages/amplify-category-api/src/provider-utils/awscloudformation/prompt-to-add-api-key.ts @@ -15,7 +15,7 @@ sandbox mode disabled in '${context.amplify.getEnvInfo().envName}', do not creat const apiKeyConfig = await askApiKeyQuestions(); const authConfig = [apiKeyConfig]; - getCfnApiArtifactHandler(context).updateArtifactsWithoutCompile({ + await getCfnApiArtifactHandler(context).updateArtifactsWithoutCompile({ version: 1, serviceModification: { serviceName: 'AppSync', From 28177017cdb475482ab1cd322a480d2fc8dd2679 Mon Sep 17 00:00:00 2001 From: Danielle Adams Date: Tue, 31 Aug 2021 13:05:15 -0400 Subject: [PATCH 9/9] refactor(cli): refactor api key prompt --- .../prompt-to-add-api-key.test.ts | 11 ----- .../prompt-to-add-api-key.ts | 9 +--- .../prompt-sandbox-mode-api-key.ts | 19 ++++++++ .../amplify-helpers/push-resources.ts | 9 +--- .../src/__tests__/resolvers/common.test.ts | 47 ------------------- 5 files changed, 22 insertions(+), 73 deletions(-) create mode 100644 packages/amplify-cli/src/extensions/amplify-helpers/prompt-sandbox-mode-api-key.ts delete mode 100644 packages/amplify-graphql-model-transformer/src/__tests__/resolvers/common.test.ts diff --git a/packages/amplify-category-api/src/__tests__/provider-utils/awscloudformation/prompt-to-add-api-key.test.ts b/packages/amplify-category-api/src/__tests__/provider-utils/awscloudformation/prompt-to-add-api-key.test.ts index 2a4803485c0..bed19bbca73 100644 --- a/packages/amplify-category-api/src/__tests__/provider-utils/awscloudformation/prompt-to-add-api-key.test.ts +++ b/packages/amplify-category-api/src/__tests__/provider-utils/awscloudformation/prompt-to-add-api-key.test.ts @@ -23,28 +23,17 @@ describe('prompt to add Api Key', () => { return { envName }; }, }, - print: { - info: jest.fn(), - }, prompt: { confirm: jest.fn(() => true), }, } as unknown as $TSContext; - jest.spyOn(ctx.print, 'info'); jest.spyOn(ctx.prompt, 'confirm'); jest.spyOn(walkthrough, 'askApiKeyQuestions'); jest.spyOn(cfnApiArtifactHandler, 'getCfnApiArtifactHandler'); await promptToAddApiKey(ctx); - expect(ctx.print.info).toHaveBeenCalledWith(` -⚠️ WARNING: Global Sandbox Mode has been enabled, which requires a valid API key. If -you'd like to disable, remove ${chalk.green('"type AMPLIFY_GLOBAL @allow_public_data_access_with_api_key"')} -from your GraphQL schema and run 'amplify push' again. If you'd like to proceed with -sandbox mode disabled in '${ctx.amplify.getEnvInfo().envName}', do not create an API Key. -`); - expect(ctx.prompt.confirm).toHaveBeenCalledWith('Would you like to create an API Key?', true); expect(walkthrough.askApiKeyQuestions).toHaveBeenCalledTimes(1); expect(cfnApiArtifactHandler.getCfnApiArtifactHandler).toHaveBeenCalledTimes(1); diff --git a/packages/amplify-category-api/src/provider-utils/awscloudformation/prompt-to-add-api-key.ts b/packages/amplify-category-api/src/provider-utils/awscloudformation/prompt-to-add-api-key.ts index 5bf1417409d..187136686bf 100644 --- a/packages/amplify-category-api/src/provider-utils/awscloudformation/prompt-to-add-api-key.ts +++ b/packages/amplify-category-api/src/provider-utils/awscloudformation/prompt-to-add-api-key.ts @@ -1,16 +1,9 @@ -import chalk from 'chalk'; +import { $TSContext } from 'amplify-cli-core'; import { askApiKeyQuestions } from './service-walkthroughs/appSync-walkthrough'; import { authConfigToAppSyncAuthType } from './utils/auth-config-to-app-sync-auth-type-bi-di-mapper'; import { getCfnApiArtifactHandler } from './cfn-api-artifact-handler'; -import { $TSContext } from 'amplify-cli-core'; export async function promptToAddApiKey(context: $TSContext): Promise { - context.print.info(` -⚠️ WARNING: Global Sandbox Mode has been enabled, which requires a valid API key. If -you'd like to disable, remove ${chalk.green('"type AMPLIFY_GLOBAL @allow_public_data_access_with_api_key"')} -from your GraphQL schema and run 'amplify push' again. If you'd like to proceed with -sandbox mode disabled in '${context.amplify.getEnvInfo().envName}', do not create an API Key. -`); if (await context.prompt.confirm('Would you like to create an API Key?', true)) { const apiKeyConfig = await askApiKeyQuestions(); const authConfig = [apiKeyConfig]; diff --git a/packages/amplify-cli/src/extensions/amplify-helpers/prompt-sandbox-mode-api-key.ts b/packages/amplify-cli/src/extensions/amplify-helpers/prompt-sandbox-mode-api-key.ts new file mode 100644 index 00000000000..9beb0eda74a --- /dev/null +++ b/packages/amplify-cli/src/extensions/amplify-helpers/prompt-sandbox-mode-api-key.ts @@ -0,0 +1,19 @@ +import chalk from 'chalk'; +import { $TSContext } from 'amplify-cli-core'; +import { promptToAddApiKey } from 'amplify-category-api'; +import { globalSandboxModeEnabled, showGlobalSandboxModeWarning } from './show-global-sandbox-mode-warning'; +import { apiKeyIsActive, hasApiKey } from './get-api-key-config'; + +export async function promptSandboxModeApiKey(context: $TSContext): Promise { + if (globalSandboxModeEnabled(context)) { + if (!apiKeyIsActive() || !hasApiKey()) { + context.print.info(` +⚠️ WARNING: Global Sandbox Mode has been enabled, which requires a valid API key. If +you'd like to disable, remove ${chalk.green('"type AMPLIFY_GLOBAL @allow_public_data_access_with_api_key"')} +from your GraphQL schema and run 'amplify push' again. If you'd like to proceed with +sandbox mode disabled in '${context.amplify.getEnvInfo().envName}', do not create an API Key. +`); + await promptToAddApiKey(context); + } else showGlobalSandboxModeWarning(context); + } +} diff --git a/packages/amplify-cli/src/extensions/amplify-helpers/push-resources.ts b/packages/amplify-cli/src/extensions/amplify-helpers/push-resources.ts index 9e3bba53885..f7354a34b69 100644 --- a/packages/amplify-cli/src/extensions/amplify-helpers/push-resources.ts +++ b/packages/amplify-cli/src/extensions/amplify-helpers/push-resources.ts @@ -4,10 +4,8 @@ import { onCategoryOutputsChange } from './on-category-outputs-change'; import { initializeEnv } from '../../initialize-env'; import { getProviderPlugins } from './get-provider-plugins'; import { getEnvInfo } from './get-env-info'; -import { globalSandboxModeEnabled, showGlobalSandboxModeWarning } from './show-global-sandbox-mode-warning'; -import { apiKeyIsActive, hasApiKey } from './get-api-key-config'; import { EnvironmentDoesNotExistError, exitOnNextTick, stateManager, $TSAny, $TSContext } from 'amplify-cli-core'; -import { promptToAddApiKey } from 'amplify-category-api'; +import { promptSandboxModeApiKey } from './prompt-sandbox-mode-api-key'; export async function pushResources( context: $TSContext, @@ -70,10 +68,7 @@ export async function pushResources( continueToPush = await context.amplify.confirmPrompt('Are you sure you want to continue?'); } - if (globalSandboxModeEnabled(context)) { - if (!apiKeyIsActive() || !hasApiKey()) await promptToAddApiKey(context); - else showGlobalSandboxModeWarning(context); - } + await promptSandboxModeApiKey(context); if (continueToPush) { try { diff --git a/packages/amplify-graphql-model-transformer/src/__tests__/resolvers/common.test.ts b/packages/amplify-graphql-model-transformer/src/__tests__/resolvers/common.test.ts deleted file mode 100644 index 8584d1090c3..00000000000 --- a/packages/amplify-graphql-model-transformer/src/__tests__/resolvers/common.test.ts +++ /dev/null @@ -1,47 +0,0 @@ -import { generateSandboxMode } from '../../resolvers'; -import { getInputType } from '../test-utils/helpers'; - -describe('generateSandboxMode', () => { - let ctx: any; - - beforeEach(() => { - ctx = { - resourceHelper: { - api: { globalSandboxModeEnabled: undefined }, - }, - }; - }); - - describe('when sandbox mode disabled', () => { - beforeEach(() => { - ctx.resourceHelper.api.globalSandboxModeEnabled = false; - }); - - it('generates unauthorized expression', () => { - const exp: any = generateSandboxMode(ctx); - const { value } = exp.expressions.find((e: any) => e.kind === 'Reference'); - - expect(value).toEqual('util.unauthorized'); - }); - }); - - describe('when sandbox mode enabled', () => { - beforeEach(() => { - ctx.resourceHelper.api.globalSandboxModeEnabled = true; - }); - - it('generates unauthorized expression for non API_KEY authorization type', () => { - const exp: any = generateSandboxMode(ctx); - const { kind, leftExpr, rightExpr } = exp.predicate; - const leftExprValue = leftExpr.expressions.find((e: any) => e.kind === 'Reference').value; - - expect(kind).toEqual('NotEquals'); - expect(leftExprValue).toEqual('util.authType'); - expect(rightExpr.value).toEqual('API_KEY'); - - const { value } = exp.expr.expressions.find((e: any) => e.kind === 'Reference'); - - expect(value).toEqual('util.unauthorized'); - }); - }); -});