diff --git a/Cpp/include/odin/user.hpp b/Cpp/include/odin/user.hpp index 69a0f58..914b1e7 100644 --- a/Cpp/include/odin/user.hpp +++ b/Cpp/include/odin/user.hpp @@ -63,6 +63,14 @@ namespace odin { f5::u8view username, f5::u8view full_name); + /// Save phone number of the given user to database, this does not commit the + /// transaction + void set_phone_number( + fostlib::pg::connection &cnx, + f5::u8view reference, + f5::u8view username, + f5::u8view phone_nummber); + /// Save email of the given user to database, this does not commit the /// transaction void set_email( diff --git a/Cpp/odin-views/registration.cpp b/Cpp/odin-views/registration.cpp index c751aaf..9f6a102 100644 --- a/Cpp/odin-views/registration.cpp +++ b/Cpp/odin-views/registration.cpp @@ -92,6 +92,12 @@ namespace { odin::set_full_name(cnx, ref, identity_id, full_name); } + if (body.has_key("phone_number")) { + const auto phone_number = + fostlib::coerce(body["phone_number"]); + odin::set_phone_number(cnx, ref, identity_id, phone_number); + } + if (body.has_key("email")) { try { const auto email = fostlib::coerce( diff --git a/Cpp/odin/user.cpp b/Cpp/odin/user.cpp index 0c9aa5d..82def2c 100644 --- a/Cpp/odin/user.cpp +++ b/Cpp/odin/user.cpp @@ -93,6 +93,19 @@ void odin::set_full_name( } +void odin::set_phone_number( + fostlib::pg::connection &cnx, + f5::u8view reference, + f5::u8view identity_id, + f5::u8view phone_number) { + fg::json user_values; + fostlib::insert(user_values, "reference", reference); + fostlib::insert(user_values, "identity_id", identity_id); + fostlib::insert(user_values, "phone_number", phone_number); + cnx.insert("odin.identity_phone_number_ledger", user_values); +} + + void odin::set_email( fostlib::pg::connection &cnx, f5::u8view reference, diff --git a/Schema/opts/phone-number/001-initial.blue.sql b/Schema/opts/phone-number/001-initial.blue.sql new file mode 100644 index 0000000..a05350b --- /dev/null +++ b/Schema/opts/phone-number/001-initial.blue.sql @@ -0,0 +1,40 @@ +INSERT INTO odin.module VALUES('opts/phone-number') ON CONFLICT (name) DO NOTHING; +INSERT INTO odin.migration VALUES('opts/phone-number', '001-initial.blue.sql'); + + +ALTER TABLE odin.identity ADD COLUMN + phone_number text NULL; + +CREATE TABLE odin.identity_phone_number_ledger ( + reference text NOT NULL, + identity_id text NOT NULL, + CONSTRAINT odin_identity_phone_number_ledger_identity_fkey + FOREIGN KEY (identity_id) + REFERENCES odin.identity_record (id) MATCH SIMPLE + ON UPDATE NO ACTION ON DELETE NO ACTION DEFERRABLE, + CONSTRAINT odin_identity_phone_number_ledger_pk PRIMARY KEY (reference, identity_id), + + changed timestamp with time zone NOT NULL DEFAULT now(), + pg_user text NOT NULL DEFAULT current_user, + + phone_number text NOT NULL, + + verified boolean DEFAULT False, + verified_timestamp timestamp with time zone, + + annotation json NOT NULL DEFAULT '{}' +); +CREATE FUNCTION odin.identity_phone_number_ledger_insert() RETURNS TRIGGER AS $body$ + BEGIN + INSERT INTO odin.identity (id, phone_number) + VALUES (NEW.identity_id, NEW.phone_number) + ON CONFLICT (id) DO UPDATE SET + phone_number = EXCLUDED.phone_number; + RETURN NULL; + END; + $body$ LANGUAGE plpgsql SECURITY DEFINER SET search_path = odin; +CREATE TRIGGER odin_identity_phone_number_ledger_insert_trigger + AFTER INSERT ON odin.identity_phone_number_ledger + FOR EACH ROW + EXECUTE PROCEDURE odin.identity_phone_number_ledger_insert(); + diff --git a/tests/registration-self.fg b/tests/registration-self.fg index 0333eb7..718134a 100644 --- a/tests/registration-self.fg +++ b/tests/registration-self.fg @@ -70,3 +70,7 @@ odin.sql.file (module.path.join ../Schema/opts/facebook/005-facebook-credentials POST odin/test/facebook/login/ok / {"access_token": "login_via_fb"} 200 POST odin/register / {"username": "login_via_fb", "password": "password1234", "email": "login_via_fb@example.com"} 422 {"message": "This email already exists"} +## Enable opts/phone module, then user can register with full-name along with username and password +odin.sql.file (module.path.join ../Schema/opts/phone-number/001-initial.blue.sql) +POST odin/register / {"username": "user_p01", "password": "password1234", "phone_number": "+661231234"} 201 +GET odin/secure/sql /user/user_p01 200 {"user": {"expires": null, "phone_number": "+661231234"}, "credentials": {"login": "user_p01"}}