nextcloud / twofactor_gateway

🔑 Second factor provider using an external messaging gateway (SMS, Telegram, Signal)
GNU Affero General Public License v3.0
109 stars 63 forks source link

Setting Phone number via API #601

Open ogamingSCV opened 10 months ago

ogamingSCV commented 10 months ago

Hello,

I am currently exploring the use of the SMS 2FA plugin for Nextcloud and was wondering if there is a method to programmatically set the phone number for SMS 2FA through an API. I am particularly interested in automating this process for user management.

Any insights or help on this matter would be greatly appreciated.

Best regards,

ostasevych commented 10 months ago

Well, I use Signal as a 2FA and have patched lib/Service/Gateway/Signal/Gateway.php in order to pass the phone number as the account id, so the variable SIGNAL_CLI_DBUS_REST_API_ACCOUNT=>+XXXYYYYYYYYY is set in config.php

        /**
         * @param IUser $user
         * @param string $identifier
         * @param string $message
         *
         * @throws SmsTransmissionException
         * 2023-06-18 patched by OS: added the system variable of the registered number/account SIGNAL_CLI_DBUS_REST_API_ACCOUNT, modified send function
         */

        public function send(IUser $user, string $identifier, string $message) {
                $client = $this->clientService->newClient();
                // determine type of gateway
                $response = $client->get($this->config->getUrl() . '/v1/about');
                if ($response->getStatusCode() === 200) {
                // new v2 style gateway https://github.com/bbernhard/signal-cli-rest-api
                        $recipient_acct = [$identifier];
                        $registered_acct = $this->config2->getSystemValue('SIGNAL_CLI_DBUS_REST_API_ACCOUNT','');
                        $response = $client->post(
                                $this->config->getUrl() . '/v2/send',
                                [
                                        'json' => [
                                                'text_mode' => 'styled',
                                                'message' => $message,
                                                'number' => $registered_acct,
                                                'recipients' => $recipient_acct
                                                 ],

                                ]
                        );
                        $body = $response->getBody();
                        $json = json_decode($body, true);
                        if ($response->getStatusCode() !== 201 || is_null($json) || !is_array($json) || !isset($json['timestamp'])) {
                                $status = $response->getStatusCode();
                                throw new SmsTransmissionException("error reported by Signal gateway, status=$status, body=$body}");
                        }
                }
                else {
                        // Try old deprecated gateway https://gitlab.com/morph027/signal-web-gateway
                        $response = $client->post(
                                $this->config->getUrl() . '/v1/send/' . $identifier,
                                [
                                        'body' => [
                                                'to' => $identifier,
                                                'message' => $message,
                                        ],
                                        'json' => [ 'message' => $message ],
                                ]
                        );
                        $body = $response->getBody();
                        $json = json_decode($body, true);

                        if ($response->getStatusCode() !== 200 || is_null($json) || !is_array($json) || !isset($json['success']) || $json['success'] !== true) {
                                $status = $response->getStatusCode();
                                throw new SmsTransmissionException("error reported by Signal gateway, status=$status, body=$body}");
                        }
                }

        }

You may reuse it somehow. Ideally, it might be great to add this configuration to webUI.