Skip to content

Commit 9ce9387

Browse files
rouzooatymic
andauthored
TelegramWebApp login integration (#1401)
* TelegramWebApp login integration * fix after review * add to monorepo-builder * add abstract methods --------- Co-authored-by: atymic <atymicq@gmail.com>
0 parents  commit 9ce9387

File tree

4 files changed

+230
-0
lines changed

4 files changed

+230
-0
lines changed

Provider.php

Lines changed: 97 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,97 @@
1+
<?php
2+
3+
namespace SocialiteProviders\TelegramWebApp;
4+
5+
use Illuminate\Support\Facades\Validator;
6+
use InvalidArgumentException;
7+
use SocialiteProviders\Manager\OAuth2\AbstractProvider;
8+
use SocialiteProviders\Manager\OAuth2\User;
9+
10+
class Provider extends AbstractProvider
11+
{
12+
/**
13+
* Unique Provider Identifier.
14+
*/
15+
public const IDENTIFIER = 'TELEGRAMWEBAPP';
16+
17+
/**
18+
* {@inheritdoc}
19+
*/
20+
public static function additionalConfigKeys(): array
21+
{
22+
return [];
23+
}
24+
25+
protected function getAuthUrl($state): string
26+
{
27+
return null;
28+
}
29+
30+
protected function getTokenUrl(): string
31+
{
32+
return null;
33+
}
34+
35+
/**
36+
* {@inheritdoc}
37+
*/
38+
protected function getUserByToken($token)
39+
{
40+
return null;
41+
}
42+
43+
/**
44+
* {@inheritdoc}
45+
*/
46+
protected function mapUserToObject(array $user)
47+
{
48+
$name = trim(sprintf('%s %s', $user['first_name'] ?? '', $user['last_name'] ?? ''));
49+
50+
return (new User())->setRaw($user)->map([
51+
'id' => $user['id'],
52+
'nickname' => $user['username'] ?? $user['first_name'],
53+
'name' => !empty($name) ? $name : null,
54+
'avatar' => $user['photo_url'] ?? null,
55+
]);
56+
}
57+
58+
/**
59+
* {@inheritdoc}
60+
*/
61+
public function user()
62+
{
63+
$data = $this->request->query();
64+
65+
if (!$this->validateTelegramHash($data)) {
66+
throw new InvalidArgumentException('Invalid Telegram WebApp data');
67+
}
68+
69+
$userString = $data['user'] ?? null;
70+
if (!$userString) {
71+
throw new InvalidArgumentException('User data not found in Telegram WebApp response');
72+
}
73+
74+
$telegramUser = json_decode($userString, true);
75+
if (!$telegramUser) {
76+
throw new InvalidArgumentException('Invalid user data format');
77+
}
78+
79+
return $this->mapUserToObject($telegramUser);
80+
}
81+
82+
private function validateTelegramHash(array $data): bool
83+
{
84+
$sign = $data['hash'];
85+
86+
$checkString = collect($data)
87+
->except('hash')
88+
->sortKeys()
89+
->transform(fn ($v, $k) => "$k=$v")
90+
->join("\n");
91+
92+
$secret = hash_hmac('sha256', $this->clientSecret, 'WebAppData', true);
93+
$calculatedHash = bin2hex(hash_hmac('sha256', $checkString, $secret, true));
94+
95+
return hash_equals($sign, $calculatedHash);
96+
}
97+
}

README.md

Lines changed: 74 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,74 @@
1+
# TelegramWebApp
2+
3+
```bash
4+
composer require socialiteproviders/telegramwebapp
5+
```
6+
7+
## Installation & Basic Usage
8+
9+
Please see the [Base Installation Guide](https://socialiteproviders.com/usage/), then follow the provider specific instructions below.
10+
11+
## Configuration
12+
13+
First of all, you must create a bot by contacting [@BotFather](http://t.me/BotFather) (https://core.telegram.org/bots#6-botfather)
14+
15+
Next you must add WebApp script to your page, please see the [Initializing Mini Apps Guide](https://core.telegram.org/bots/webapps#initializing-mini-apps).
16+
17+
> Don't forget to set your website URL using `/setdomain`
18+
19+
Then, you need to add your bot's configuration to `config/services.php`. The bot username is required, `client_id` must be `null`. The provider will also ask permission for the bot to write to the user.
20+
21+
```php
22+
'telegramwebapp' => [
23+
'client_id' => null,
24+
'client_secret' => env('TELEGRAM_TOKEN'),
25+
'redirect' => env('TELEGRAM_REDIRECT_URI'),
26+
],
27+
```
28+
29+
### Add provider event listener
30+
31+
#### Laravel 11+
32+
33+
In Laravel 11, the default `EventServiceProvider` provider was removed. Instead, add the listener using the `listen` method on the `Event` facade, in your `AppServiceProvider` `boot` method.
34+
35+
* Note: You do not need to add anything for the built-in socialite providers unless you override them with your own providers.
36+
37+
```php
38+
Event::listen(function (\SocialiteProviders\Manager\SocialiteWasCalled $event) {
39+
$event->extendSocialite('telegramwebapp', \SocialiteProviders\TelegramWebApp\Provider::class);
40+
});
41+
```
42+
<details>
43+
<summary>
44+
Laravel 10 or below
45+
</summary>
46+
Configure the package's listener to listen for `SocialiteWasCalled` events.
47+
48+
Add the event to your `listen[]` array in `app/Providers/EventServiceProvider`. See the [Base Installation Guide](https://socialiteproviders.com/usage/) for detailed instructions.
49+
50+
```php
51+
protected $listen = [
52+
\SocialiteProviders\Manager\SocialiteWasCalled::class => [
53+
// ... other providers
54+
\SocialiteProviders\TelegramWebApp\TelegramWebAppExtendSocialite::class.'@handle',
55+
],
56+
];
57+
```
58+
</details>
59+
60+
### Usage
61+
62+
You should now be able to use the provider like you would regularly use Socialite (assuming you have the facade installed):
63+
64+
```php
65+
return Socialite::driver('telegramwebapp')->redirect();
66+
```
67+
68+
### Returned User fields
69+
70+
- ``id``
71+
- ``first_name``
72+
- ``last_name``
73+
- ``username``
74+
- ``photo_url``

TelegramWebAppExtendSocialite.php

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
<?php
2+
3+
namespace SocialiteProviders\TelegramWebApp;
4+
5+
use SocialiteProviders\Manager\SocialiteWasCalled;
6+
7+
class TelegramWebAppExtendSocialite
8+
{
9+
/**
10+
* Register the provider.
11+
*
12+
* @param \SocialiteProviders\Manager\SocialiteWasCalled $socialiteWasCalled
13+
*/
14+
public function handle(SocialiteWasCalled $socialiteWasCalled)
15+
{
16+
$socialiteWasCalled->extendSocialite('telegramwebapp', Provider::class);
17+
}
18+
}

composer.json

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
{
2+
"name": "socialiteproviders/telegramwebapp",
3+
"description": "Telegram WebApp Authentication Provider for Laravel Socialite",
4+
"license": "MIT",
5+
"keywords": [
6+
"telegram",
7+
"laravel",
8+
"oauth",
9+
"provider",
10+
"socialite",
11+
"webapp",
12+
"telegramwebapp"
13+
],
14+
"authors": [
15+
{
16+
"name": "Kirill Kudryashov",
17+
"email": "rouzoo.pro@gmail.com"
18+
}
19+
],
20+
"support": {
21+
"issues": "https://github.com/socialiteproviders/providers/issues",
22+
"source": "https://github.com/socialiteproviders/providers",
23+
"docs": "https://socialiteproviders.com/telegramwebapp"
24+
},
25+
"require": {
26+
"php": "^8.2",
27+
"socialiteproviders/manager": "^4.4"
28+
},
29+
"extra": {
30+
"laravel": {
31+
"aliases": {
32+
"Socialite": "Laravel\\Socialite\\Facades\\Socialite"
33+
}
34+
}
35+
},
36+
"autoload": {
37+
"psr-4": {
38+
"SocialiteProviders\\TelegramWebApp\\": ""
39+
}
40+
}
41+
}

0 commit comments

Comments
 (0)