@@ -144,10 +144,22 @@ class CdnDefinitionProvider extends DefinitionProvider {
144144
145145 void _applySecretsFromRoot (Map <String , dynamic > root) {
146146 final artifacts = _asMap (root['artifacts' ]);
147- if (artifacts == null ) return ;
147+ if (artifacts == null ) {
148+ // No artifacts -> ensure runtime secrets can't linger.
149+ if (_runtimeSecrets.isNotEmpty) {
150+ _assetEnv? .removeWhere ((k, _) => _runtimeSecrets.containsKey (k));
151+ _runtimeSecrets.clear ();
152+ }
153+ return ;
154+ }
148155
149156 // Per requirement: artifacts.secrets is a flat key/value mapping.
150157 final rawSecrets = _asMap (artifacts['secrets' ]);
158+ // Always replace runtime secrets on refresh so deleted keys don't linger.
159+ if (_runtimeSecrets.isNotEmpty) {
160+ _assetEnv? .removeWhere ((k, _) => _runtimeSecrets.containsKey (k));
161+ _runtimeSecrets.clear ();
162+ }
151163 if (rawSecrets == null || rawSecrets.isEmpty) return ;
152164
153165 rawSecrets.forEach ((k, v) {
@@ -212,7 +224,6 @@ class CdnDefinitionProvider extends DefinitionProvider {
212224 if (cachedManifest != null && cachedManifest.isNotEmpty) {
213225 try {
214226 final root = _decodeManifestRoot (cachedManifest);
215- _applySecretsFromRoot (root);
216227 _rebuildFromRoot (root);
217228 } catch (e) {
218229 // Clear invalid cache
@@ -280,13 +291,20 @@ class CdnDefinitionProvider extends DefinitionProvider {
280291 }
281292
282293 bool _hasEncryptionKey () {
283- final key = (_assetEnv ?? const {})['ENSEMBLE_ENCRYPTION_KEY' ] ??
284- dotenv.env['ENSEMBLE_ENCRYPTION_KEY' ];
285- return key != null && key.trim ().isNotEmpty;
294+ final fromAssets = (_assetEnv ?? const {})['ENSEMBLE_ENCRYPTION_KEY' ];
295+ if (fromAssets != null && fromAssets.trim ().isNotEmpty) return true ;
296+
297+ if (! dotenv.isInitialized) return false ;
298+ final fromDotenv = dotenv.env['ENSEMBLE_ENCRYPTION_KEY' ];
299+ return fromDotenv != null && fromDotenv.trim ().isNotEmpty;
286300 }
287301
288302 String ? _getSecret (String name) {
289- return (_assetEnv ?? const {})[name] ?? dotenv.env[name];
303+ final fromAssets = (_assetEnv ?? const {})[name];
304+ if (fromAssets != null ) return fromAssets;
305+
306+ if (! dotenv.isInitialized) return null ;
307+ return dotenv.env[name];
290308 }
291309
292310 static Uint8List _b64UrlDecode (String input) {
@@ -461,7 +479,6 @@ class CdnDefinitionProvider extends DefinitionProvider {
461479 final newEtag = fetched['etag' ] as String ? ;
462480 final root = _decodeManifestRoot (jsonString);
463481
464- _applySecretsFromRoot (root);
465482 _rebuildFromRoot (root);
466483 await _refreshTranslationsAtRuntime ();
467484 _etag = newEtag ?? _etag;
@@ -510,7 +527,6 @@ class CdnDefinitionProvider extends DefinitionProvider {
510527 _etag = fetched['etag' ] as String ? ;
511528
512529 final root = _decodeManifestRoot (jsonString);
513- _applySecretsFromRoot (root);
514530 _rebuildFromRoot (root);
515531
516532 // Save to persistent cache
@@ -567,6 +583,7 @@ class CdnDefinitionProvider extends DefinitionProvider {
567583 }
568584
569585 http.Response resp;
586+ var fetchedEncrypted = false ;
570587 if (shouldUseEncrypted) {
571588 final encryptedHeaders = Map <String , String >.from (headers);
572589 final manifestKey = _getSecret ('ENSEMBLE_MANIFEST_KEY' );
@@ -575,6 +592,7 @@ class CdnDefinitionProvider extends DefinitionProvider {
575592 }
576593
577594 resp = await http.get (encryptedUri, headers: encryptedHeaders);
595+ fetchedEncrypted = resp.statusCode != 404 ;
578596 // If encrypted manifest doesn't exist for this app, fall back to plain.
579597 if (resp.statusCode == 404 ) {
580598 resp = await http.get (plainUri, headers: headers);
@@ -597,7 +615,7 @@ class CdnDefinitionProvider extends DefinitionProvider {
597615 String jsonString = decodedBody;
598616
599617 // If we fetched the encrypted-manifest endpoint successfully, decrypt it.
600- if (shouldUseEncrypted && resp.request ? .url == encryptedUri ) {
618+ if (shouldUseEncrypted && fetchedEncrypted ) {
601619 jsonString = _decryptEncryptedManifestEnvelope (decodedBody);
602620 }
603621 if (jsonString.isEmpty) return null ;
@@ -634,6 +652,7 @@ class CdnDefinitionProvider extends DefinitionProvider {
634652 _themeMapping = null ;
635653 _defaultLocale = null ;
636654 _appConfig = null ;
655+ _applySecretsFromRoot (root);
637656
638657 final artifacts = _asMap (root['artifacts' ]);
639658 if (artifacts == null ) return ;
0 commit comments