From 2bdb4f03d05d135dbf0b8d8989add707771cecc8 Mon Sep 17 00:00:00 2001 From: celestora Date: Sat, 30 Mar 2024 13:56:38 +0200 Subject: [PATCH] feat(OAuth): add oauth flow --- Web/Presenters/VKAPIPresenter.php | 38 ++++ Web/Presenters/templates/VKAPI/OAuthLogin.xml | 193 ++++++++++++++++++ Web/routes.yml | 2 + locales/en.strings | 9 + locales/ru.strings | 9 + 5 files changed, 251 insertions(+) create mode 100644 Web/Presenters/templates/VKAPI/OAuthLogin.xml diff --git a/Web/Presenters/VKAPIPresenter.php b/Web/Presenters/VKAPIPresenter.php index 1247d83d..e906ce50 100644 --- a/Web/Presenters/VKAPIPresenter.php +++ b/Web/Presenters/VKAPIPresenter.php @@ -318,4 +318,42 @@ final class VKAPIPresenter extends OpenVKPresenter header("Content-Length: $size"); exit($payload); } + + function renderOAuthLogin() { + $this->assertUserLoggedIn(); + + $client = $this->queryParam("client_name"); + $postmsg = $this->queryParam("prefers_postMessage") ?? '0'; + $stale = $this->queryParam("accepts_stale") ?? '0'; + $origin = NULL; + $url = $this->queryParam("redirect_uri"); + if(is_null($url) || is_null($client)) + exit("Error: redirect_uri and client_name params are required."); + + if($url != "about:blank") { + if(!filter_var($url, FILTER_VALIDATE_URL)) + exit("Error: Invalid URL passed to redirect_uri."); + + $parsedUrl = (object) parse_url($url); + if($parsedUrl->scheme != 'https' && $parsedUrl->scheme != 'http') + exit("Error: redirect_uri should either point to about:blank or to a web resource."); + + $origin = "$parsedUrl->scheme://$parsedUrl->host"; + if(!is_null($parsedUrl->port ?? NULL)) + $origin .= ":$parsedUrl->port"; + + $url .= strpos($url, '?') === false ? '?' : '&'; + } else { + $url .= "#"; + if($postmsg == '1') { + exit("Error: prefers_postMessage can only be set if redirect_uri is not about:blank"); + } + } + + $this->template->clientName = $client; + $this->template->usePostMessage = $postmsg == '1'; + $this->template->acceptsStale = $stale == '1'; + $this->template->origin = $origin; + $this->template->redirectUri = $url; + } } diff --git a/Web/Presenters/templates/VKAPI/OAuthLogin.xml b/Web/Presenters/templates/VKAPI/OAuthLogin.xml new file mode 100644 index 00000000..40cf10d5 --- /dev/null +++ b/Web/Presenters/templates/VKAPI/OAuthLogin.xml @@ -0,0 +1,193 @@ + + + + + Получение доступа | OpenVK + + + +
+
+
+
+ + +
+
+ +
+
+
+ {_app}, + + {if is_null($origin)} + {tr("identifies_itself_as", $clientName)}{else} + {tr("located_at_url", $origin)}{/if}, {_wants_your_token}. +
+ +
+ {_app_will_have_access_to}
+ {_oauth_scope_all|noescape}. +
+ +
+ + {_oauth_deny} +
+
+
+ + {script "js/node_modules/msgpack-lite/dist/msgpack.min.js"} + {script "js/al_api.js"} + + + diff --git a/Web/routes.yml b/Web/routes.yml index d4496f03..ac0189ac 100644 --- a/Web/routes.yml +++ b/Web/routes.yml @@ -373,6 +373,8 @@ routes: handler: "VKAPI->route" - url: "/token" handler: "VKAPI->tokenLogin" + - url: "/authorize" + handler: "VKAPI->OAuthLogin" - url: "/admin/sandbox" handler: "About->sandbox" - url: "/admin/chandler/groups" diff --git a/locales/en.strings b/locales/en.strings index 697c95b5..e44313e9 100644 --- a/locales/en.strings +++ b/locales/en.strings @@ -775,6 +775,15 @@ "disable_2fa" = "Turn off 2FA"; "viewing" = "View"; +/* OAuth */ +"identifies_itself_as" = "that identifies itself as $1"; +"located_at_url" = "located at $1"; +"wants_your_token" = "wants to access your account"; +"app_will_have_access_to" = "App will have access to:"; +"oauth_scope_all" = "profile information, status, list of friends, photos, wall posts, audios, videos, notifications, fishing rod handle, messages, gifts, your e-mail, polls, communities, discussions, notes, payment method, likes and comments"; +"oauth_grant" = "Allow"; +"oauth_deny" = "Deny"; + /* Sorting */ "sort_randomly" = "Sort randomly"; diff --git a/locales/ru.strings b/locales/ru.strings index b88d8d05..1220387f 100644 --- a/locales/ru.strings +++ b/locales/ru.strings @@ -737,6 +737,15 @@ "disable_2fa" = "Отключить 2FA"; "viewing" = "Просмотреть"; +/* OAuth */ +"identifies_itself_as" = "идентифицирующее себя как $1"; +"located_at_url" = "располагающееся по адресу $1"; +"wants_your_token" = "запрашивает доступ к вашему аккаунту"; +"app_will_have_access_to" = "Приложению будут доступны:"; +"oauth_scope_all" = "информация страницы, обновление статуса, список друзей, фотографии, публикация записей, аудиозаписи, видео, уведомления, сообщения, подарки, ваш адрес электронной почты, опросы, группы, обсуждения, заметки, голоса, лайки и комментарии"; +"oauth_grant" = "Разрешить"; +"oauth_deny" = "Отмена"; + /* Sorting */ "sort_randomly" = "Сортировать случайно";