diff --git a/cmd/zitadel/authz.yaml b/cmd/zitadel/authz.yaml index 49f9e6d095..3f69f637f7 100644 --- a/cmd/zitadel/authz.yaml +++ b/cmd/zitadel/authz.yaml @@ -45,6 +45,7 @@ InternalAuthZ: - "user.grant.write" - "user.grant.delete" - "user.membership.read" + - "user.credential.write" - "features.read" - "policy.read" - "policy.write" @@ -120,6 +121,7 @@ InternalAuthZ: - "user.grant.write" - "user.grant.delete" - "user.membership.read" + - "user.credential.write" - "features.read" - "policy.read" - "policy.write" @@ -192,6 +194,7 @@ InternalAuthZ: - "user.grant.write" - "user.grant.delete" - "user.membership.read" + - "user.credential.write" - "features.read" - "policy.read" - "policy.write" diff --git a/docs/docs/apis/proto/management.md b/docs/docs/apis/proto/management.md index 6ebc734fb8..780b38f1ed 100644 --- a/docs/docs/apis/proto/management.md +++ b/docs/docs/apis/proto/management.md @@ -529,6 +529,20 @@ Returns all configured passwordless authenticators POST: /users/{user_id}/passwordless/_search +### AddPasswordlessRegistration + +> **rpc** AddPasswordlessRegistration([AddPasswordlessRegistrationRequest](#addpasswordlessregistrationrequest)) +[AddPasswordlessRegistrationResponse](#addpasswordlessregistrationresponse) + +Adds a new passwordless authenticator link to the user and returns it directly +This link enables the user to register a new device if current passwordless devices are all platform authenticators +e.g. User has already registered Windows Hello and wants to register FaceID on the iPhone + + + + POST: /users/{user_id}/passwordless/_link + + ### SendPasswordlessRegistration > **rpc** SendPasswordlessRegistration([SendPasswordlessRegistrationRequest](#sendpasswordlessregistrationrequest)) @@ -3369,6 +3383,30 @@ This is an empty request +### AddPasswordlessRegistrationRequest + + + +| Field | Type | Description | Validation | +| ----- | ---- | ----------- | ----------- | +| user_id | string | - | string.min_len: 1
string.max_len: 200
| + + + + +### AddPasswordlessRegistrationResponse + + + +| Field | Type | Description | Validation | +| ----- | ---- | ----------- | ----------- | +| details | zitadel.v1.ObjectDetails | - | | +| link | string | - | | +| expiration | google.protobuf.Duration | - | | + + + + ### AddProjectGrantMemberRequest diff --git a/internal/api/grpc/management/user.go b/internal/api/grpc/management/user.go index 6d87747c54..6ac983c61f 100644 --- a/internal/api/grpc/management/user.go +++ b/internal/api/grpc/management/user.go @@ -493,6 +493,19 @@ func (s *Server) ListHumanPasswordless(ctx context.Context, req *mgmt_pb.ListHum }, nil } +func (s *Server) AddPasswordlessRegistration(ctx context.Context, req *mgmt_pb.AddPasswordlessRegistrationRequest) (*mgmt_pb.AddPasswordlessRegistrationResponse, error) { + ctxData := authz.GetCtxData(ctx) + initCode, err := s.command.HumanAddPasswordlessInitCode(ctx, req.UserId, ctxData.OrgID) + if err != nil { + return nil, err + } + return &mgmt_pb.AddPasswordlessRegistrationResponse{ + Details: object.AddToDetailsPb(initCode.Sequence, initCode.ChangeDate, initCode.ResourceOwner), + Link: initCode.Link(s.systemDefaults.Notifications.Endpoints.PasswordlessRegistration), + Expiration: durationpb.New(initCode.Expiration), + }, nil +} + func (s *Server) SendPasswordlessRegistration(ctx context.Context, req *mgmt_pb.SendPasswordlessRegistrationRequest) (*mgmt_pb.SendPasswordlessRegistrationResponse, error) { ctxData := authz.GetCtxData(ctx) initCode, err := s.command.HumanSendPasswordlessInitCode(ctx, req.UserId, ctxData.OrgID) diff --git a/proto/zitadel/management.proto b/proto/zitadel/management.proto index a31d33a36e..10fad473fa 100644 --- a/proto/zitadel/management.proto +++ b/proto/zitadel/management.proto @@ -574,6 +574,19 @@ service ManagementService { }; } + // Adds a new passwordless authenticator link to the user and returns it directly + // This link enables the user to register a new device if current passwordless devices are all platform authenticators + // e.g. User has already registered Windows Hello and wants to register FaceID on the iPhone + rpc AddPasswordlessRegistration(AddPasswordlessRegistrationRequest) returns (AddPasswordlessRegistrationResponse) { + option (google.api.http) = { + post: "/users/{user_id}/passwordless/_link" + body: "*" + }; + option (zitadel.v1.auth_option) = { + permission: "user.credential.write" + }; + } + // Adds a new passwordless authenticator link to the user and sends it to the registered email address // This link enables the user to register a new device if current passwordless devices are all platform authenticators // e.g. User has already registered Windows Hello and wants to register FaceID on the iPhone @@ -583,7 +596,7 @@ service ManagementService { body: "*" }; option (zitadel.v1.auth_option) = { - permission: "authenticated" + permission: "user.write" }; } @@ -3290,6 +3303,16 @@ message ListHumanPasswordlessResponse { repeated zitadel.user.v1.WebAuthNToken result = 1; } +message AddPasswordlessRegistrationRequest { + string user_id = 1 [(validate.rules).string = {min_len: 1, max_len: 200}]; +} + +message AddPasswordlessRegistrationResponse { + zitadel.v1.ObjectDetails details = 1; + string link = 2; + google.protobuf.Duration expiration = 3; +} + message SendPasswordlessRegistrationRequest { string user_id = 1 [(validate.rules).string = {min_len: 1, max_len: 200}]; }