feat: user v2 phone verification (#6309)

* feat: add phone change and code verification for user v2 api

* feat: add phone change and code verification for user v2 api

* fix: add ignored phone.proto

* fix: integration tests

* Update proto/zitadel/user/v2alpha/user_service.proto

* Update idp_template.go

---------

Co-authored-by: Livio Spring <livio.a@gmail.com>
This commit is contained in:
Stefan Benz
2023-08-03 06:42:59 +02:00
committed by GitHub
parent a1942ecdaa
commit ef012d0081
15 changed files with 1511 additions and 8 deletions

View File

@@ -0,0 +1,30 @@
syntax = "proto3";
package zitadel.user.v2alpha;
option go_package = "github.com/zitadel/zitadel/pkg/grpc/user/v2alpha;user";
import "google/api/annotations.proto";
import "google/api/field_behavior.proto";
import "protoc-gen-openapiv2/options/annotations.proto";
import "validate/validate.proto";
message SetHumanPhone {
string phone = 1 [
(validate.rules).string = {min_len: 0, max_len: 200},
(grpc.gateway.protoc_gen_openapiv2.options.openapiv2_field) = {
max_length: 200;
example: "\"+41791234567\"";
}
];
oneof verification {
SendPhoneVerificationCode send_code = 2;
ReturnPhoneVerificationCode return_code = 3;
bool is_verified = 4 [(validate.rules).bool.const = true];
}
}
message SendPhoneVerificationCode {}
message ReturnPhoneVerificationCode {}

View File

@@ -6,6 +6,7 @@ import "zitadel/object/v2alpha/object.proto";
import "zitadel/protoc_gen_zitadel/v2/options.proto";
import "zitadel/user/v2alpha/auth.proto";
import "zitadel/user/v2alpha/email.proto";
import "zitadel/user/v2alpha/phone.proto";
import "zitadel/user/v2alpha/idp.proto";
import "zitadel/user/v2alpha/password.proto";
import "zitadel/user/v2alpha/user.proto";
@@ -158,6 +159,56 @@ service UserService {
};
}
// Change the phone of a user
rpc SetPhone(SetPhoneRequest) returns (SetPhoneResponse) {
option (google.api.http) = {
post: "/v2alpha/users/{user_id}/phone"
body: "*"
};
option (zitadel.protoc_gen_zitadel.v2.options) = {
auth_option: {
permission: "authenticated"
}
};
option (grpc.gateway.protoc_gen_openapiv2.options.openapiv2_operation) = {
summary: "Change the user phone";
description: "Change the phone number of a user. If the state is set to not verified, a verification code will be generated, which can be either returned or sent to the user by sms."
responses: {
key: "200"
value: {
description: "OK";
}
};
};
}
// Verify the phone with the provided code
rpc VerifyPhone (VerifyPhoneRequest) returns (VerifyPhoneResponse) {
option (google.api.http) = {
post: "/v2alpha/users/{user_id}/phone/_verify"
body: "*"
};
option (zitadel.protoc_gen_zitadel.v2.options) = {
auth_option: {
permission: "authenticated"
}
};
option (grpc.gateway.protoc_gen_openapiv2.options.openapiv2_operation) = {
summary: "Verify the phone";
description: "Verify the phone with the generated code."
responses: {
key: "200"
value: {
description: "OK";
}
};
};
}
rpc RegisterPasskey (RegisterPasskeyRequest) returns (RegisterPasskeyResponse) {
option (google.api.http) = {
post: "/v2alpha/users/{user_id}/passkeys"
@@ -584,6 +635,7 @@ message AddHumanUserRequest{
(validate.rules).message.required = true,
(google.api.field_behavior) = REQUIRED
];
SetHumanPhone phone = 10;
repeated SetMetadataEntry metadata = 6;
oneof password_type {
Password password = 7;
@@ -596,6 +648,7 @@ message AddHumanUserResponse {
string user_id = 1;
zitadel.object.v2alpha.Details details = 2;
optional string email_code = 3;
optional string phone_code = 4;
}
message SetEmailRequest{
@@ -657,6 +710,65 @@ message VerifyEmailResponse{
zitadel.object.v2alpha.Details details = 1;
}
message SetPhoneRequest{
string user_id = 1 [
(validate.rules).string = {min_len: 1, max_len: 200},
(google.api.field_behavior) = REQUIRED,
(grpc.gateway.protoc_gen_openapiv2.options.openapiv2_field) = {
min_length: 1;
max_length: 200;
example: "\"69629026806489455\"";
}
];
string phone = 2 [
(validate.rules).string = {min_len: 1, max_len: 200},
(google.api.field_behavior) = REQUIRED,
(grpc.gateway.protoc_gen_openapiv2.options.openapiv2_field) = {
min_length: 1;
max_length: 200;
example: "\"+41791234567\"";
}
];
// if no verification is specified, an sms is sent
oneof verification {
SendPhoneVerificationCode send_code = 3;
ReturnPhoneVerificationCode return_code = 4;
bool is_verified = 5 [(validate.rules).bool.const = true];
}
}
message SetPhoneResponse{
zitadel.object.v2alpha.Details details = 1;
// in case the verification was set to return_code, the code will be returned
optional string verification_code = 2;
}
message VerifyPhoneRequest{
string user_id = 1 [
(validate.rules).string = {min_len: 1, max_len: 200},
(google.api.field_behavior) = REQUIRED,
(grpc.gateway.protoc_gen_openapiv2.options.openapiv2_field) = {
min_length: 1;
max_length: 200;
example: "\"69629026806489455\"";
}
];
string verification_code = 2 [
(validate.rules).string = {min_len: 1, max_len: 20},
(google.api.field_behavior) = REQUIRED,
(grpc.gateway.protoc_gen_openapiv2.options.openapiv2_field) = {
min_length: 1;
max_length: 20;
example: "\"SKJd342k\"";
description: "\"the verification code generated during the set phone request\"";
}
];
}
message VerifyPhoneResponse{
zitadel.object.v2alpha.Details details = 1;
}
message RegisterPasskeyRequest{
string user_id = 1 [
(validate.rules).string = {min_len: 1, max_len: 200},