Skip to content

Commit 0e74b52

Browse files
committed
Merge branch 'develop' into feature/fix-language-settings-behaivour
2 parents 04f599e + 4dcb8c3 commit 0e74b52

File tree

89 files changed

+2369
-2280
lines changed

Some content is hidden

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

89 files changed

+2369
-2280
lines changed

.github/workflows/build.yml

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -18,10 +18,10 @@ jobs:
1818
name: Run Tests
1919
runs-on: ubuntu-latest
2020
steps:
21-
- uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0
21+
- uses: actions/checkout@1af3b93b6815bc44a9784bd300feb67ff0d1eeb3 # v6.0.0
2222
with:
2323
fetch-depth: 0 # Shallow clones should be disabled for a better relevancy of analysis
24-
- uses: actions/setup-node@49933ea5288caeca8642d1e84afbd3f7d6820020 # v4.4.0
24+
- uses: actions/setup-node@395ad3262231945c25e8478fd5baf05154b1d79f # v6.1.0
2525
with:
2626
node-version: ${{ env.NODE_VERSION }}
2727
cache: 'npm'
@@ -36,7 +36,7 @@ jobs:
3636
working-directory: frontend
3737
run: npm run dist
3838
- name: SonarCloud Scan Frontend
39-
uses: SonarSource/sonarqube-scan-action@fd88b7d7ccbaefd23d8f36f73b59db7a3d246602 # v6.0.0
39+
uses: SonarSource/sonarqube-scan-action@a31c9398be7ace6bbfaf30c0bd5d415f843d45e9 # v7.0.0
4040
with:
4141
projectBaseDir: frontend
4242
args: >
@@ -49,13 +49,13 @@ jobs:
4949
env:
5050
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} # Needed to get PR information, if any
5151
SONAR_TOKEN: ${{ secrets.SONAR_TOKEN }}
52-
- uses: actions/setup-java@dded0888837ed1f317902acf8a20df0ad188d165 # v5.0.0
52+
- uses: actions/setup-java@f2beeb24e141e01a676f977032f5a29d81c9e27e # v5.1.0
5353
with:
5454
distribution: 'temurin'
5555
java-version: ${{ env.JAVA_VERSION }}
5656
cache: 'maven'
5757
- name: Cache SonarCloud packages
58-
uses: actions/cache@0057852bfaa89a56745cba8c7296529d2fc39830 # v4.3.0
58+
uses: actions/cache@9255dc7a253b0ccc959486e2bca901246202afeb # v5.0.1
5959
with:
6060
path: ~/.sonar/cache
6161
key: ${{ runner.os }}-sonar
@@ -95,8 +95,8 @@ jobs:
9595
contents: read
9696
packages: write
9797
steps:
98-
- uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0
99-
- uses: actions/setup-node@49933ea5288caeca8642d1e84afbd3f7d6820020 # v4.4.0
98+
- uses: actions/checkout@1af3b93b6815bc44a9784bd300feb67ff0d1eeb3 # v6.0.0
99+
- uses: actions/setup-node@395ad3262231945c25e8478fd5baf05154b1d79f # v6.1.0
100100
with:
101101
node-version: ${{ env.NODE_VERSION }}
102102
cache: 'npm'
@@ -112,7 +112,7 @@ jobs:
112112
run: ./mvnw versions:set --file pom.xml -DnewVersion=${GITHUB_REF##*/}
113113
- name: Docker metadata
114114
id: meta
115-
uses: docker/metadata-action@c1e51972afc2121e065aed6d45c65596fe445f3f # v5.8.0
115+
uses: docker/metadata-action@c299e40c65443455700f0fdfc63efafe5b349051 # v5.10.0
116116
with:
117117
images: ghcr.io/cryptomator/hub
118118
tags: |

.github/workflows/keycloak.yml

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -24,8 +24,8 @@ jobs:
2424
attestations: write
2525
packages: write
2626
steps:
27-
- uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0
28-
- uses: actions/setup-node@49933ea5288caeca8642d1e84afbd3f7d6820020 # v4.4.0
27+
- uses: actions/checkout@1af3b93b6815bc44a9784bd300feb67ff0d1eeb3 # v6.0.0
28+
- uses: actions/setup-node@395ad3262231945c25e8478fd5baf05154b1d79f # v6.1.0
2929
with:
3030
node-version: ${{ env.NODE_VERSION }}
3131
cache: 'npm'
@@ -37,7 +37,7 @@ jobs:
3737
working-directory: keycloak/themes/cryptomator/common/resources
3838
run: npm run build
3939
- name: Set up QEMU
40-
uses: docker/setup-qemu-action@29109295f81e9208d7d86ff1c6c12d2833863392 # v3.6.0
40+
uses: docker/setup-qemu-action@c7c53464625b32c7a7e944ae62b3e17d2b600130 # v3.7.0
4141
- name: Set up Docker Buildx
4242
uses: docker/setup-buildx-action@e468171a9de216ec08956ac3ada2f0791b6bd435 # v3.11.1
4343
- name: Login to GHCR

CHANGELOG.md

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,9 +7,22 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
77

88
## [Unreleased](https://github.com/cryptomator/hub/compare/1.4.6...HEAD)
99

10+
### Added
11+
12+
- Show pictures of the groups in the Vaults member list. (#375)
13+
1014
### Changed
1115

1216
- Updated Keycloak to 26.4.7
17+
- Update Quarkus to 3.20.4 LTS
18+
- Improved efficiency of keycloak-to-hub data sync (#377)
19+
- Improved efficiency of group-based access permission checks (#372)
20+
- Migrated aes-siv and base encoding libraries to [`@noble/ciphers`](https://github.com/paulmillr/noble-ciphers) and [`@scure/base`](https://github.com/paulmillr/scure-base/) (#373)
21+
22+
### Security
23+
24+
- CVE-2025-64756, CVE-2025-64118: removed `glob` and `tar` dependencies
25+
- CVE-2025-64718, CVE-2025-62522: updated `js-yaml` and `vite`
1326

1427
## [1.4.6](https://github.com/cryptomator/hub/compare/1.4.5...1.4.6)
1528

backend/.idea/codeStyles/Project.xml

Lines changed: 1 addition & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

backend/.idea/inspectionProfiles/Project_Default.xml

Lines changed: 1 addition & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

backend/pom.xml

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -10,13 +10,13 @@
1010
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
1111
<project.jdk.version>21</project.jdk.version>
1212
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
13-
<quarkus.platform.version>3.20.3</quarkus.platform.version>
13+
<quarkus.platform.version>3.20.4</quarkus.platform.version>
1414
<jwt.version>4.5.0</jwt.version>
1515
<compiler-plugin.version>3.14.1</compiler-plugin.version>
16-
<dependency-plugin.version>3.8.1</dependency-plugin.version>
16+
<dependency-plugin.version>3.9.0</dependency-plugin.version>
1717
<surefire-plugin.version>3.5.4</surefire-plugin.version>
1818
<failsafe-plugin.version>3.5.4</failsafe-plugin.version>
19-
<junit-tree-reporter.version>1.4.0</junit-tree-reporter.version>
19+
<junit-tree-reporter.version>1.5.1</junit-tree-reporter.version>
2020
</properties>
2121

2222
<dependencyManagement>

backend/src/main/java/org/cryptomator/hub/api/GroupDto.java

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -8,8 +8,8 @@ public final class GroupDto extends AuthorityDto {
88
@JsonProperty("memberSize")
99
public final Integer memberSize;
1010

11-
GroupDto(@JsonProperty("id") String id, @JsonProperty("name") String name, @JsonProperty("memberSize") Integer memberSize) {
12-
super(id, Type.GROUP, name, null);
11+
GroupDto(@JsonProperty("id") String id, @JsonProperty("name") String name, @JsonProperty("pictureUrl") String pictureUrl, @JsonProperty("memberSize") Integer memberSize) {
12+
super(id, Type.GROUP, name, pictureUrl);
1313
this.memberSize = memberSize;
1414
}
1515

@@ -19,6 +19,6 @@ public static GroupDto fromEntity(Group group) {
1919

2020
public static GroupDto fromEntity(Group group, boolean withMemberSize) {
2121
Integer memberSize = withMemberSize ? group.getMemberSize() : null;
22-
return new GroupDto(group.getId(), group.getName(), memberSize);
22+
return new GroupDto(group.getId(), group.getName(), group.getPictureUrl(), memberSize);
2323
}
2424
}

backend/src/main/java/org/cryptomator/hub/api/MemberDto.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@ public static MemberDto fromEntity(User user, VaultAccess.Role role) {
2929
}
3030

3131
public static MemberDto fromEntity(Group group, VaultAccess.Role role) {
32-
return new MemberDto(group.getId(), Type.GROUP, group.getName(), null, null, null, role, group.getMemberSize());
32+
return new MemberDto(group.getId(), Type.GROUP, group.getName(), group.getPictureUrl(), null, null, role, group.getMemberSize());
3333
}
3434

3535
}

backend/src/main/java/org/cryptomator/hub/api/VaultResource.java

Lines changed: 5 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
import com.auth0.jwt.JWT;
44
import com.auth0.jwt.algorithms.Algorithm;
55
import com.auth0.jwt.exceptions.JWTVerificationException;
6+
import com.fasterxml.jackson.annotation.JsonInclude;
67
import com.fasterxml.jackson.annotation.JsonProperty;
78
import io.quarkus.security.identity.SecurityIdentity;
89
import io.vertx.core.http.HttpServerRequest;
@@ -255,7 +256,7 @@ public Response removeAuthority(@PathParam("vaultId") UUID vaultId, @PathParam("
255256
@VaultRole(VaultAccess.Role.OWNER) // may throw 403
256257
@Transactional
257258
@Produces(MediaType.APPLICATION_JSON)
258-
@Operation(summary = "list devices requiring access rights", description = "lists all devices owned by vault members, that don't have a device-specific masterkey yet")
259+
@Operation(summary = "list users requiring access rights", description = "lists all users, who don't have a user-specific vault key yet")
259260
@APIResponse(responseCode = "200")
260261
@APIResponse(responseCode = "403", description = "not a vault owner")
261262
public List<UserDto> getUsersRequiringAccessGrant(@PathParam("vaultId") UUID vaultId) {
@@ -384,17 +385,14 @@ public Response grantAccess(@PathParam("vaultId") UUID vaultId, @NotEmpty Map<St
384385
@GET
385386
@Path("/{vaultId}")
386387
@RolesAllowed("user")
387-
// @VaultRole(VaultAccess.Role.MEMBER) // TODO: members and admin may do this...
388+
@VaultRole(value = {VaultAccess.Role.MEMBER, VaultAccess.Role.OWNER}, bypassForRealmRole = true, realmRole = "admin", onMissingVault = VaultRole.OnMissingVault.NOT_FOUND)
388389
@Produces(MediaType.APPLICATION_JSON)
389390
@Transactional
390391
@Operation(summary = "gets a vault")
391392
@APIResponse(responseCode = "200")
392393
@APIResponse(responseCode = "403", description = "requesting user is neither a vault member nor has the admin role")
393394
public VaultDto get(@PathParam("vaultId") UUID vaultId) {
394395
Vault vault = vaultRepo.findByIdOptional(vaultId).orElseThrow(NotFoundException::new);
395-
if (vault.getEffectiveMembers().stream().noneMatch(u -> u.getId().equals(jwt.getSubject())) && !identity.getRoles().contains("admin")) {
396-
throw new ForbiddenException("Requesting user is not a member of the vault");
397-
}
398396
return VaultDto.fromEntity(vault);
399397
}
400398

@@ -506,8 +504,8 @@ public Response claimOwnership(@PathParam("vaultId") UUID vaultId, @FormParam("p
506504
return Response.ok(VaultDto.fromEntity(vault), MediaType.APPLICATION_JSON).build();
507505
}
508506

509-
510-
public record VaultDto(@JsonProperty("id") UUID id,
507+
@JsonInclude(JsonInclude.Include.NON_NULL)
508+
public record VaultDto(@JsonProperty("id") @NotNull UUID id,
511509
@JsonProperty("name") @NoHtmlOrScriptChars @NotBlank String name,
512510
@JsonProperty("description") @NoHtmlOrScriptChars String description,
513511
@JsonProperty("archived") boolean archived,

backend/src/main/java/org/cryptomator/hub/entities/Authority.java

Lines changed: 18 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212
import jakarta.persistence.NamedQuery;
1313
import jakarta.persistence.Table;
1414

15+
import java.util.Collection;
1516
import java.util.List;
1617
import java.util.Objects;
1718
import java.util.stream.Stream;
@@ -41,6 +42,9 @@ public class Authority {
4142
@Column(name = "name", nullable = false)
4243
private String name;
4344

45+
@Column(name = "picture_url")
46+
private String pictureUrl;
47+
4448
public String getId() {
4549
return id;
4650
}
@@ -57,6 +61,14 @@ public void setName(String name) {
5761
this.name = name;
5862
}
5963

64+
public String getPictureUrl() {
65+
return pictureUrl;
66+
}
67+
68+
public void setPictureUrl(String pictureUrl) {
69+
this.pictureUrl = pictureUrl;
70+
}
71+
6072
@Override
6173
public String toString() {
6274
return "Authority{" +
@@ -71,12 +83,13 @@ public boolean equals(Object o) {
7183
if (o == null || getClass() != o.getClass()) return false;
7284
Authority authority = (Authority) o;
7385
return Objects.equals(id, authority.id)
86+
&& Objects.equals(pictureUrl, authority.pictureUrl)
7487
&& Objects.equals(name, authority.name);
7588
}
7689

7790
@Override
7891
public int hashCode() {
79-
return Objects.hash(id, name);
92+
return Objects.hash(id, name, pictureUrl);
8093
}
8194

8295
@ApplicationScoped
@@ -87,7 +100,10 @@ public Stream<Authority> byName(String name) {
87100
}
88101

89102
public Stream<Authority> findAllInList(List<String> ids) {
90-
return find("#Authority.allInList", Parameters.with("ids", ids)).stream();
103+
return Batch.of(200).run(ids, Stream.empty(), (batch, result) -> {
104+
var partial = find("#Authority.allInList", Parameters.with("ids", batch));
105+
return Stream.concat(result, partial.stream());
106+
});
91107
}
92108
}
93109
}

0 commit comments

Comments
 (0)