Skip to content

Commit 905afe5

Browse files
committed
Merge branch 'release' into 'master'
PB-39559 Set version to v4.12.0 See merge request passbolt/passbolt-ce-api!345
2 parents d96c8b6 + 288a118 commit 905afe5

File tree

87 files changed

+3232
-548
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

87 files changed

+3232
-548
lines changed

CHANGELOG.md

+57
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,63 @@
22
All notable changes to this project will be documented in this file.
33
This project adheres to [Semantic Versioning](http://semver.org/).
44

5+
## [4.12.0] - 2025-03-12
6+
### Added
7+
- PB-39395 As an administrator I can contain permissions when upgrading folders to v5 format
8+
- PB-39394 As an administrator I can contain permissions when upgrading resources to v5 format
9+
- PB-38850 As an administrator I cannot rotate entities while two metadata keys are active
10+
- PB-37699 As an administrator I can upgrade folders to v5 format
11+
- PB-37363 As an administrator I can rotate metadata keys encrypting folders metadata
12+
- PB-36582 As an administrator I cannot reuse a previously deleted metadata key
13+
14+
### Fixed
15+
- PB-39512 Fix during metadata upgrade process, the resource_type_id field is now updated in the database
16+
- PB-39399 Adds missing fields to metadata private keys in index response
17+
- PB-39393 Fix limit value is null in pagination header response for rotate & upgrade endpoints
18+
- PB-38770 Fix email subject for delete resource email when resource is v5
19+
- PB-38791 Fix 500 error on the duo MFA setup & verify page when duo service is unavailable
20+
- PB-38771 Fix unable to expire the metadata key due to expired datetime format
21+
22+
### Maintenance
23+
- PB-39629 Set next minimum PHP version to 8.2 as passbolt v5 will not support lower PHP versions
24+
25+
## [4.12.0-rc.1] - 2025-03-06
26+
### Added
27+
- PB-39395 As an administrator I can contain permissions when upgrading folders to v5 format
28+
- PB-39394 As an administrator I can contain permissions when upgrading resources to v5 format
29+
- PB-38850 As an administrator I cannot rotate entities while two metadata keys are active
30+
- PB-37699 As an administrator I can upgrade folders to v5 format
31+
- PB-37363 As an administrator I can rotate metadata keys encrypting folders metadata
32+
- PB-36582 As an administrator I cannot reuse a previously deleted metadata key
33+
34+
### Fixed
35+
- PB-39512 Fix during metadata upgrade process, the resource_type_id field is now updated in the database
36+
- PB-39399 Adds missing fields to metadata private keys in index response
37+
- PB-39393 Fix limit value is null in pagination header response for rotate & upgrade endpoints
38+
- PB-38770 Fix email subject for delete resource email when resource is v
39+
- PB-38791 Fix 500 error on the duo MFA setup & verify page when duo service is unavailable
40+
- PB-38771 Fix unable to expire the metadata key due to expired datetime format
41+
42+
### Maintenance
43+
- PB-39629 Set next minimum PHP version to 8.2 as passbolt v5 will not support lower PHP versions
44+
45+
## [4.12.0-test.1] - 2025-03-05
46+
### Added
47+
- PB-39395 As an administrator I can contain permissions when upgrading folders to v5 format
48+
- PB-39394 As an administrator I can contain permissions when upgrading resources to v5 format
49+
- PB-38850 As an administrator I cannot rotate entities while two metadata keys are active
50+
- PB-37699 As an administrator I can upgrade folders to v5 format
51+
- PB-37363 As an administrator I can rotate metadata keys encrypting folders metadata
52+
- PB-36582 As an administrator I cannot reuse a previously deleted metadata key
53+
54+
### Fixed
55+
- PB-39512 Fix during metadata upgrade process, the resource_type_id field is now updated in the database
56+
- PB-39399 Adds missing fields to metadata private keys in index response
57+
- PB-39393 Fix limit value is null in pagination header response for rotate & upgrade endpoints
58+
- PB-38770 Fix email subject for delete resource email when resource is v
59+
- PB-38791 Fix 500 error on the duo MFA setup & verify page when duo service is unavailable
60+
- PB-38771 Fix unable to expire the metadata key due to expired datetime format
61+
562
## [4.11.1] - 2025-02-17
663
### Security
764
- PB-39045 Fix empty fullBaseUrl leading to Host header injection attack

RELEASE_NOTES.md

+28-6
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,31 @@
1-
Release song: https://youtu.be/U16Xg_rQZkA?si=cVcmovGWluuo8oYj
1+
Release song: https://www.youtube.com/watch?v=pBZs_Py-1_0
22

3-
Passbolt is pleased to announce the immediate availability of version v4.11.1. This version is a targeted security release of the API focusing on fixing the security issue reported by a security researcher.
3+
Passbolt v4.12.0 introduces the final update in the version 4 series. This release completes the groundwork for version 5 and allows integrators to test the migration directly from the UI ahead of the stable release.
44

5-
We would like to express our appreciation to the community for their assistance in making Passbolt more secure. Further details can be found in [the incident report](https://www.passbolt.com/incidents/host-header-injection-vulnerability).
5+
As always, this version also addresses community-reported issues, including fixes for UI inconsistencies and multi-selection shortcuts that were not working across all environments.
66

7-
## [4.11.1] - 2025-02-17
8-
### Security
9-
- PB-39045 Fix empty fullBaseUrl leading to Host header injection attack
7+
As a final update of the v4 series, system administrators are invited to upgrade their version of PHP to meet Passbolt v5’s minimum requirements: PHP 8.2. We posted a guide in our Weblog to help you with the process:
8+
[Preparing for Passbolt v5: PHP 8.2 Requirement](https://www.passbolt.com/blog/preparing-for-passbolt-v5-php-8-2-requirement).
9+
10+
Thank you to the community for your feedback and patience — we’re almost there!
11+
12+
13+
## [4.12.0] - 2025-03-12
14+
### Added
15+
- PB-39395 As an administrator I can contain permissions when upgrading folders to v5 format
16+
- PB-39394 As an administrator I can contain permissions when upgrading resources to v5 format
17+
- PB-38850 As an administrator I cannot rotate entities while two metadata keys are active
18+
- PB-37699 As an administrator I can upgrade folders to v5 format
19+
- PB-37363 As an administrator I can rotate metadata keys encrypting folders metadata
20+
- PB-36582 As an administrator I cannot reuse a previously deleted metadata key
21+
22+
### Fixed
23+
- PB-39512 Fix during metadata upgrade process, the resource_type_id field is now updated in the database
24+
- PB-39399 Adds missing fields to metadata private keys in index response
25+
- PB-39393 Fix limit value is null in pagination header response for rotate & upgrade endpoints
26+
- PB-38770 Fix email subject for delete resource email when resource is v5
27+
- PB-38791 Fix 500 error on the duo MFA setup & verify page when duo service is unavailable
28+
- PB-38771 Fix unable to expire the metadata key due to expired datetime format
29+
30+
### Maintenance
31+
- PB-39629 Set next minimum PHP version to 8.2 as passbolt v5 will not support lower PHP versions

config/version.php

+3-3
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,11 @@
11
<?php
22
return [
33
'passbolt' => [
4-
'version' => '4.11.1',
5-
'name' => 'Rebel Rebel',
4+
'version' => '4.12.0',
5+
'name' => 'Rusty Cage',
66
],
77
'php' => [
88
'minVersion' => '7.4',
9-
'nextMinVersion' => '8.1',
9+
'nextMinVersion' => '8.2',
1010
],
1111
];

package-lock.json

+7-8
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

+1-1
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@
2424
"jquery": "^3.5.1",
2525
"lockfile-lint": "^4.14.0",
2626
"openpgp": "^5.11.1",
27-
"passbolt-styleguide": "^4.11.0"
27+
"passbolt-styleguide": "^4.12.0"
2828
},
2929
"scripts": {
3030
"lint": "npm run lint:lockfile",

plugins/PassboltCe/Folders/src/Model/Table/FoldersTable.php

+10-1
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@
2929
use Passbolt\Metadata\Model\Rule\IsFolderV5ToV4DowngradeAllowedRule;
3030
use Passbolt\Metadata\Model\Rule\IsMetadataKeyTypeAllowedBySettingsRule;
3131
use Passbolt\Metadata\Model\Rule\IsMetadataKeyTypeSharedOnSharedItemRule;
32+
use Passbolt\Metadata\Model\Rule\IsSharedMetadataKeyUniqueActiveRule;
3233
use Passbolt\Metadata\Model\Rule\IsV4ToV5UpgradeAllowedRule;
3334
use Passbolt\Metadata\Model\Rule\IsValidEncryptedMetadataRule;
3435
use Passbolt\Metadata\Model\Rule\MetadataKeyIdExistsInRule;
@@ -127,6 +128,9 @@ public function initialize(array $config): void
127128
'FoldersRelations.foreign_model' => 'Resource',
128129
],
129130
]);
131+
$this->belongsTo('MetadataKeys', [
132+
'className' => 'Passbolt/Metadata.MetadataKeys',
133+
]);
130134
}
131135

132136
/**
@@ -259,9 +263,14 @@ public function buildRulesV5(RulesChecker $rules): RulesChecker
259263
'message' => __('The metadata key is marked as expired.'),
260264
]);
261265

266+
$rules->add(new IsSharedMetadataKeyUniqueActiveRule(), 'isSharedMetadataKeyUniqueActive', [
267+
'errorField' => 'metadata_key_id',
268+
'message' => __('The shared metadata key should be unique.'),
269+
]);
270+
262271
$rules->add(new IsValidEncryptedMetadataRule(), 'isValidEncryptedMetadata', [
263272
'errorField' => 'metadata',
264-
'message' => __('The resource metadata provided can not be decrypted.'),
273+
'message' => __('The folder metadata provided cannot be decrypted.'),
265274
]);
266275

267276
$rules->addUpdate(

plugins/PassboltCe/Folders/src/Model/Traits/Folders/FoldersFindersTrait.php

+88
Original file line numberDiff line numberDiff line change
@@ -21,11 +21,13 @@
2121
use App\Model\Table\PermissionsTable;
2222
use App\Model\Traits\Query\CaseInsensitiveSearchQueryTrait;
2323
use Cake\Database\Expression\IdentifierExpression;
24+
use Cake\Database\Expression\QueryExpression;
2425
use Cake\ORM\Query;
2526
use Cake\Validation\Validation;
2627
use InvalidArgumentException;
2728
use Passbolt\Folders\Model\Behavior\FolderizableBehavior;
2829
use Passbolt\Folders\Model\Entity\Folder;
30+
use Passbolt\Metadata\Model\Entity\MetadataKey;
2931

3032
/**
3133
* Trait FoldersFindersTrait
@@ -154,6 +156,28 @@ public function findIndex(string $userId, ?array $options = [])
154156
return $query;
155157
}
156158

159+
/**
160+
* Returns all folders with expired metadata key.
161+
*
162+
* @return \Cake\ORM\Query
163+
*/
164+
public function findMetadataRotateKeyIndex(): Query
165+
{
166+
$query = $this->find();
167+
168+
return $query
169+
->where([
170+
'Folders.metadata_key_type' => MetadataKey::TYPE_SHARED_KEY,
171+
$query->newExpr()->isNotNull('Folders.metadata'),
172+
$query->newExpr()->isNotNull('Folders.metadata_key_id'),
173+
])
174+
->innerJoin(['MetadataKeys' => 'metadata_keys'], [
175+
'MetadataKeys.id' => new IdentifierExpression('Folders.metadata_key_id'),
176+
$query->newExpr()->isNotNull('MetadataKeys.expired'),
177+
])
178+
->disableHydration();
179+
}
180+
157181
/**
158182
* Build the query that fetches data for folders view
159183
*
@@ -259,4 +283,68 @@ public function filterQueryByParentIds(Query $query, array $parentIds): Query
259283
return $q->where(['OR' => $conditions]);
260284
});
261285
}
286+
287+
/**
288+
* Returns all resources in v4 format that need to be upgraded.
289+
*
290+
* @param array $options query options
291+
* @return \Cake\ORM\Query
292+
*/
293+
public function findMetadataUpgradeIndex(array $options): Query
294+
{
295+
$query = $this->find('v4')->disableHydration();
296+
297+
$containPermissions = (bool)($options['contain']['permissions'] ?? false);
298+
if ($containPermissions) {
299+
$query->contain('Permissions');
300+
}
301+
302+
if (!isset($options['filter']['is-shared'])) {
303+
return $query;
304+
}
305+
306+
$isShared = $options['filter']['is-shared'];
307+
$groupPermissionsCount = $this->Permissions->find()
308+
->select(['permissions_on_groups' => 'COUNT(*)'])
309+
->where([
310+
'Permissions.aco_foreign_key' => $query->identifier('Folders.id'),
311+
'Permissions.aco' => PermissionsTable::FOLDER_ACO,
312+
'Permissions.aro' => PermissionsTable::GROUP_ARO,
313+
]);
314+
$userPermissionsCount = $this->Permissions->find()
315+
->select(['permissions_on_users' => 'COUNT(*)'])
316+
->where([
317+
'Permissions.aco_foreign_key' => $query->identifier('Folders.id'),
318+
'Permissions.aco' => PermissionsTable::FOLDER_ACO,
319+
'Permissions.aro' => PermissionsTable::USER_ARO,
320+
]);
321+
if ($isShared === true) {
322+
// Is shared if at least one permission is a group permission
323+
// OR if at least two permissions are user permissions
324+
$query->where(function (QueryExpression $exp) use ($groupPermissionsCount, $userPermissionsCount) {
325+
return $exp->or(function (QueryExpression $or) use ($groupPermissionsCount, $userPermissionsCount) {
326+
return $or->gte($userPermissionsCount, 2)->gte($groupPermissionsCount, 1);
327+
});
328+
});
329+
} elseif ($isShared === false) {
330+
// Is not shared if no permission is a group permission
331+
// AND the only permission is a user permission
332+
$query->where(function (QueryExpression $exp) use ($groupPermissionsCount, $userPermissionsCount) {
333+
return $exp->eq($groupPermissionsCount, 0)->eq($userPermissionsCount, 1);
334+
});
335+
}
336+
337+
return $query;
338+
}
339+
340+
/**
341+
* @param \Cake\ORM\Query $query Query
342+
* @return \Cake\ORM\Query
343+
*/
344+
public function findV4(Query $query): Query
345+
{
346+
return $query->where([
347+
$query->newExpr()->isNull('Folders.metadata'),
348+
]);
349+
}
262350
}

plugins/PassboltCe/Folders/tests/Factory/FolderFactory.php

+1
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@
3434
* @method \Passbolt\Folders\Model\Entity\Folder getEntity()
3535
* @method \Passbolt\Folders\Model\Entity\Folder[] getEntities()
3636
* @method static \Passbolt\Folders\Model\Entity\Folder get($primaryKey, array $options = [])
37+
* @method static \Passbolt\Folders\Model\Entity\Folder firstOrFail($conditions = null)()
3738
*/
3839
class FolderFactory extends CakephpBaseFactory
3940
{

plugins/PassboltCe/Metadata/config/routes.php

+28
Original file line numberDiff line numberDiff line change
@@ -101,6 +101,20 @@
101101
['prefix' => 'Upgrade', 'controller' => 'MetadataUpgradeResourcesPost', 'action' => 'post']
102102
)
103103
->setMethods(['POST']);
104+
105+
$routes
106+
->connect(
107+
'/folders',
108+
['prefix' => 'Upgrade', 'controller' => 'MetadataUpgradeFoldersIndex', 'action' => 'index']
109+
)
110+
->setMethods(['GET']);
111+
112+
$routes
113+
->connect(
114+
'/folders',
115+
['prefix' => 'Upgrade', 'controller' => 'MetadataUpgradeFoldersPost', 'action' => 'post']
116+
)
117+
->setMethods(['POST']);
104118
});
105119

106120
/**
@@ -122,5 +136,19 @@
122136
['prefix' => 'RotateKey', 'controller' => 'MetadataRotateKeyResourcesPost', 'action' => 'post']
123137
)
124138
->setMethods(['POST']);
139+
140+
$routes
141+
->connect(
142+
'/folders',
143+
['prefix' => 'RotateKey', 'controller' => 'MetadataRotateKeyFoldersIndex', 'action' => 'index']
144+
)
145+
->setMethods(['GET']);
146+
147+
$routes
148+
->connect(
149+
'/folders',
150+
['prefix' => 'RotateKey', 'controller' => 'MetadataRotateKeyFoldersPost', 'action' => 'post']
151+
)
152+
->setMethods(['POST']);
125153
});
126154
});

0 commit comments

Comments
 (0)