@@ -23,6 +23,7 @@ const archiver = require('archiver')
2323const SupportedRuntimes = [ 'sequence' , 'blackbox' , 'nodejs:10' , 'nodejs:12' , 'nodejs:14' , 'nodejs:16' , 'nodejs:18' , 'nodejs:20' , 'nodejs:22' , 'nodejs:24' ]
2424const { HttpProxyAgent } = require ( 'http-proxy-agent' )
2525const PatchedHttpsProxyAgent = require ( './PatchedHttpsProxyAgent.js' )
26+ const { getCliEnv, DEFAULT_ENV } = require ( '@adobe/aio-lib-env' )
2627
2728// must cover 'deploy-service[-region][.env].app-builder[.int|.corp].adp.adobe.io/runtime
2829const SUPPORTED_ADOBE_ANNOTATION_ENDPOINT_REGEXES = [
@@ -41,6 +42,7 @@ const ANNOTATION_WEB_EXPORT = 'web-export'
4142const ANNOTATION_RAW_HTTP = 'raw-http'
4243const ANNOTATION_REQUIRE_ADOBE_AUTH = 'require-adobe-auth'
4344const ANNOTATION_REQUIRE_WHISK_AUTH = 'require-whisk-auth'
45+ const ANNOTATION_INCLUDE_IMS_CREDENTIALS = 'include-ims-credentials'
4446const VALUE_YES = 'yes'
4547const VALUE_RAW = 'raw'
4648
@@ -1186,6 +1188,106 @@ function rewriteActionsWithAdobeAuthAnnotation (packages, deploymentPackages) {
11861188 }
11871189}
11881190
1191+ /**
1192+ * This function implements the support for the `include-ims-credentials` annotation.
1193+ * It will expand the IMS_OAUTH_S2S environment variable into an input object stored under params.__ims_oauth_s2s and params.__ims_env
1194+ *
1195+ * @access private
1196+ * @param {ManifestPackages } packages the manifest packages
1197+ * @returns {ManifestPackages } newPackages, rewritten package with added inputs
1198+ */
1199+ function rewriteActionsWithAdobeIncludeIMSCredentialsAnnotation ( packages ) {
1200+ // avoid side effects, do not modify input packages
1201+ const newPackages = cloneDeep ( packages )
1202+
1203+ const imsAuthObject = loadIMSCredentialsFromEnv ( )
1204+
1205+ // traverse all actions in all packages
1206+ Object . keys ( newPackages ) . forEach ( ( key ) => {
1207+ if ( newPackages [ key ] . actions ) {
1208+ Object . keys ( newPackages [ key ] . actions ) . forEach ( ( actionName ) => {
1209+ const thisAction = newPackages [ key ] . actions [ actionName ]
1210+ const newInputs = getIncludeIMSCredentialsAnnotationInputs ( thisAction , imsAuthObject )
1211+ if ( newInputs ) {
1212+ if ( ! thisAction . inputs ) {
1213+ thisAction . inputs = { }
1214+ }
1215+ Object . entries ( newInputs ) . forEach ( ( [ k , v ] ) => { thisAction . inputs [ k ] = v } )
1216+ aioLogger . debug ( `processed annotation '${ ANNOTATION_INCLUDE_IMS_CREDENTIALS } ' for action '${ key } /${ actionName } '.` )
1217+ }
1218+ } )
1219+ }
1220+ } )
1221+ return newPackages
1222+ }
1223+
1224+ /**
1225+ * Load the IMS credentials from the environment variables.
1226+ *
1227+ * @returns {object } the IMS auth object
1228+ */
1229+ function loadIMSCredentialsFromEnv ( ) {
1230+ // constants
1231+ const IMS_OAUTH_S2S_ENV_KEY = 'IMS_OAUTH_S2S'
1232+
1233+ const imsAuthObject = {
1234+ client_id : process . env [ `${ IMS_OAUTH_S2S_ENV_KEY } _CLIENT_ID` ] ,
1235+ client_secret : process . env [ `${ IMS_OAUTH_S2S_ENV_KEY } _CLIENT_SECRET` ] ,
1236+ org_id : process . env [ `${ IMS_OAUTH_S2S_ENV_KEY } _ORG_ID` ] ,
1237+ scopes : ( ( ) => {
1238+ try {
1239+ return JSON . parse ( process . env [ `${ IMS_OAUTH_S2S_ENV_KEY } _SCOPES` ] )
1240+ } catch ( e ) {
1241+ return process . env [ `${ IMS_OAUTH_S2S_ENV_KEY } _SCOPES` ] // pass in string as is
1242+ }
1243+ } ) ( )
1244+ }
1245+ return imsAuthObject
1246+ }
1247+
1248+ /**
1249+ * Get the inputs for the include-ims-credentials annotation.
1250+ * Throws an error if the imsAuthObject is incomplete.
1251+ *
1252+ * @param {object } thisAction the action to process
1253+ * @param {object } imsAuthObject the IMS auth object
1254+ * @returns {object|undefined } the inputs or undefined with a warning
1255+ */
1256+ function getIncludeIMSCredentialsAnnotationInputs ( thisAction , imsAuthObject ) {
1257+ const env = getCliEnv ( ) || DEFAULT_ENV
1258+
1259+ const IMS_OAUTH_S2S_INPUT = '__ims_oauth_s2s'
1260+ const IMS_ENV_INPUT = '__ims_env'
1261+ const IMS_OAUTH_S2S_ENV_KEY = 'IMS_OAUTH_S2S'
1262+
1263+ // check if the annotation is defined
1264+ if ( thisAction . annotations ?. [ ANNOTATION_INCLUDE_IMS_CREDENTIALS ] ) {
1265+ // check if the IMS credentials are loaded properly, if not emit a warning
1266+ if ( Object . keys ( imsAuthObject ) . length === 0 ) {
1267+ throw new Error ( `Credentials for the project are missing, please ensure the Console Workspace is configured with an OAuth server to server credential.
1268+ Unset the annotation '${ ANNOTATION_INCLUDE_IMS_CREDENTIALS } ' if you don't want to include credentials.` )
1269+ }
1270+ const missingEnvVars = [ ]
1271+ if ( ! imsAuthObject . client_id ) {
1272+ missingEnvVars . push ( `${ IMS_OAUTH_S2S_ENV_KEY } _CLIENT_ID` )
1273+ }
1274+ if ( ! imsAuthObject . client_secret ) {
1275+ missingEnvVars . push ( `${ IMS_OAUTH_S2S_ENV_KEY } _CLIENT_SECRET` )
1276+ }
1277+ if ( ! imsAuthObject . org_id ) {
1278+ missingEnvVars . push ( `${ IMS_OAUTH_S2S_ENV_KEY } _ORG_ID` )
1279+ }
1280+ if ( ! imsAuthObject . scopes ) {
1281+ missingEnvVars . push ( `${ IMS_OAUTH_S2S_ENV_KEY } _SCOPES` )
1282+ }
1283+ if ( missingEnvVars . length > 0 ) {
1284+ throw new Error ( `Credentials for the project are incomplete. Missing '${ missingEnvVars . join ( '|' ) } ' env variables.
1285+ Unset the annotation '${ ANNOTATION_INCLUDE_IMS_CREDENTIALS } ' if you don't want to include credentials.` )
1286+ }
1287+ return { [ IMS_OAUTH_S2S_INPUT ] : { ...imsAuthObject } , [ IMS_ENV_INPUT ] : env }
1288+ }
1289+ }
1290+
11891291/**
11901292 *
11911293 * Process the manifest and deployment content and returns deployment entities.
@@ -1210,11 +1312,14 @@ function processPackage (packages,
12101312
12111313 const isAdobeEndpoint = SUPPORTED_ADOBE_ANNOTATION_ENDPOINT_REGEXES . some ( regex => regex . test ( owOptions . apihost ) )
12121314 if ( isAdobeEndpoint ) {
1315+ // rewrite packages in case there are any `include-ims-credentials` annotations
1316+ const newPackages = rewriteActionsWithAdobeIncludeIMSCredentialsAnnotation ( pkgs )
1317+
12131318 // rewrite packages in case there are any `require-adobe-auth` annotations
12141319 // this is a temporary feature and will be replaced by a native support in Adobe I/O Runtime
1215- const { newPackages , newDeploymentPackages } = rewriteActionsWithAdobeAuthAnnotation ( pkgs , deploymentPkgs )
1216- pkgs = newPackages
1217- deploymentPkgs = newDeploymentPackages
1320+ const ret = rewriteActionsWithAdobeAuthAnnotation ( newPackages , deploymentPkgs )
1321+ pkgs = ret . newPackages
1322+ deploymentPkgs = ret . newDeploymentPackages
12181323 }
12191324
12201325 const pkgAndDeps = [ ]
@@ -2185,5 +2290,7 @@ module.exports = {
21852290 dumpActionsBuiltInfo,
21862291 safeParse,
21872292 isSupportedActionKind,
2293+ getIncludeIMSCredentialsAnnotationInputs,
2294+ loadIMSCredentialsFromEnv,
21882295 DEFAULT_PACKAGE_RESERVED_NAME
21892296}
0 commit comments