1<?php
2
3use dokuwiki\Form\Form;
4use dokuwiki\plugin\twofactor\OtpField;
5use dokuwiki\plugin\twofactor\Provider;
6
7/**
8 * 2fa provider using an Telegram
9 */
10class action_plugin_twofactortelegram extends Provider
11{
12    /** @inheritdoc */
13    public function getLabel()
14    {
15        $label = $this->getLang('name');
16        $chat_id = $this->settings->get('chat_id');
17        if ($chat_id) $label .= ': ' . $chat_id;
18        return $label;
19    }
20
21    /** @inheritdoc */
22    public function isConfigured()
23    {
24        return $this->settings->get('chat_id') &&
25            $this->settings->get('verified');
26
27    }
28
29    /** @inheritdoc */
30    public function renderProfileForm(Form $form)
31    {
32        $chat_id = $this->settings->get('chat_id');
33
34        if (!$chat_id) {
35            $form->addHTML('<p>' . $this->getLang('intro') . '</p>');
36            $form->addTextInput('new_chat_id', $this->getLang('chat_id'))->attr('autocomplete', 'off');
37        } else {
38            $form->addHTML('<p>' . $this->getLang('verifynotice') . '</p>');
39            $form->addElement(new OtpField('verify'));
40        }
41
42        return $form;
43    }
44
45    /** @inheritdoc */
46    public function handleProfileForm()
47    {
48        global $INPUT;
49        global $USERINFO;
50
51        if ($INPUT->str('verify')) {
52            // verification code given, check the code
53            if ($this->checkCode($INPUT->str('verify'))) {
54                $this->settings->set('verified', true);
55            } else {
56                $this->settings->delete('chat_id');
57            }
58        } elseif ($INPUT->str('new_chat_id')) {
59            $new_chat_id = $INPUT->str('new_chat_id');
60
61            // new chat_id has been, set init verification
62            $this->settings->set('chat_id', $new_chat_id);
63
64            try {
65                $this->initSecret();
66                $code = $this->generateCode();
67                $info = $this->transmitMessage($code);
68                msg(hsc($info), 1);
69            } catch (\Exception $e) {
70                msg(hsc($e->getMessage()), -1);
71                $this->settings->delete('chat_id');
72            }
73        }
74    }
75
76    /** @inheritdoc */
77    public function transmitMessage($code)
78    {
79        $chat_id = $this->settings->get('chat_id');
80        $token = $this->getConf('bot_token');
81
82        if (!$chat_id) throw new \Exception($this->getLang('codesentfail'));
83        if (!$token) throw new \Exception($this->getLang('codesentfail'));
84
85		$text = rawurlencode($this->getLang('text'));
86		$code = rawurlencode("`$code`");
87		$url = "https://api.telegram.org/bot{$token}/sendMessage?chat_id={$chat_id}&text={$text}{$code}&parse_mode=MarkdownV2";
88		$result = file_get_contents($url);
89
90        if (!$result) throw new \Exception($this->getLang('codesentfail'));
91
92        return $this->getLang('codesent');
93    }
94}
95