Merge branch 'master' into bugfix/noid/delete-notes-on-actor-delete

pull/412/head
Maxence Lange 2019-02-20 19:56:06 -01:00 zatwierdzone przez GitHub
commit 6c93bd45e7
Nie znaleziono w bazie danych klucza dla tego podpisu
ID klucza GPG: 4AEE18F83AFDEB23
31 zmienionych plików z 12615 dodań i 11963 usunięć

Wyświetl plik

@ -59,8 +59,8 @@ lint-fix:
# Cleaning
clean:
rm -rf $(build_dir)
rm -f js/social.js
rm -f js/social.js.map
rm -fr js/
mkdir js/
clean-dev:
rm -rf node_modules

Wyświetl plik

@ -54,6 +54,10 @@ return [
['name' => 'ActivityPub#followers', 'url' => '/@{username}/followers', 'verb' => 'GET'],
['name' => 'ActivityPub#following', 'url' => '/@{username}/following', 'verb' => 'GET'],
['name' => 'OStatus#subscribe', 'url' => '/ostatus/follow/{uri}', 'verb' => 'GET'],
['name' => 'OStatus#followRemote', 'url' => '/api/v1/ostatus/followRemote/{local}', 'verb' => 'GET'],
['name' => 'OStatus#getLink', 'url' => '/api/v1/ostatus/link/{local}/{account}', 'verb' => 'GET'],
['name' => 'SocialPub#displayPost', 'url' => '/@{username}/{postId}', 'verb' => 'GET'],
['name' => 'Local#streamHome', 'url' => '/api/v1/stream/home', 'verb' => 'GET'],

30
l10n/es_AR.js 100644
Wyświetl plik

@ -0,0 +1,30 @@
OC.L10N.register(
"social",
{
"Social" : "Social",
"🎉 Nextcloud becomes part of the federated social networks!" : "🎉 ¡Nextcloud se convierte en parte de las redes sociales federadas!",
"Social needs the .well-known automatic discovery to be properly set up. If Nextcloud is not installed in the root of the domain, it is often the case that Nextcloud can't configure this automatically. To use Social, the admin of this Nextcloud instance needs to manually configure the .well-known redirects: " : "Lo social necesita que el descubrimiento automático bien conocido se configure correctamente. Si Nextcloud no está instalado en la raíz del dominio, a menudo es el caso que Nextcloud no puede configurar esto automáticamente. Para usar Social, el administrador de esta instancia de Nextcloud necesita configurar manualmente los redireccionamientos conocidos.",
"Open documentation" : "Abrir documentación",
"Social app setup" : "Configuración de la aplicación social",
"Finish setup" : "Terminar la configuración",
"Home" : "Casa",
"Direct messages" : "Mensajes directos",
"Profile" : "Perfil",
"Local timeline" : "Línea de tiempo local",
"Global timeline" : "Línea de tiempo global",
"Post publicly" : "Publicar públicamente",
"Post to followers" : "Publicar en seguidores",
"Post to recipients" : "Publicar en destinatarios",
"Post unlisted" : "Publicar sin listar",
"Direct" : "Directo",
"Post to mentioned users only" : "Publicar solo para los usuarios mencionados",
"Unlisted" : "No listado",
"Do not post to public timelines" : "No publicar en líneas de tiempo públicas",
"Followers" : "Seguidores",
"Post to followers only" : "Publicar solo en seguidores",
"Public" : "Público",
"Follow" : "Seguir",
"posts" : "publicaciones",
"following" : "siguiendo"
},
"nplurals=2; plural=(n != 1);");

28
l10n/es_AR.json 100644
Wyświetl plik

@ -0,0 +1,28 @@
{ "translations": {
"Social" : "Social",
"🎉 Nextcloud becomes part of the federated social networks!" : "🎉 ¡Nextcloud se convierte en parte de las redes sociales federadas!",
"Social needs the .well-known automatic discovery to be properly set up. If Nextcloud is not installed in the root of the domain, it is often the case that Nextcloud can't configure this automatically. To use Social, the admin of this Nextcloud instance needs to manually configure the .well-known redirects: " : "Lo social necesita que el descubrimiento automático bien conocido se configure correctamente. Si Nextcloud no está instalado en la raíz del dominio, a menudo es el caso que Nextcloud no puede configurar esto automáticamente. Para usar Social, el administrador de esta instancia de Nextcloud necesita configurar manualmente los redireccionamientos conocidos.",
"Open documentation" : "Abrir documentación",
"Social app setup" : "Configuración de la aplicación social",
"Finish setup" : "Terminar la configuración",
"Home" : "Casa",
"Direct messages" : "Mensajes directos",
"Profile" : "Perfil",
"Local timeline" : "Línea de tiempo local",
"Global timeline" : "Línea de tiempo global",
"Post publicly" : "Publicar públicamente",
"Post to followers" : "Publicar en seguidores",
"Post to recipients" : "Publicar en destinatarios",
"Post unlisted" : "Publicar sin listar",
"Direct" : "Directo",
"Post to mentioned users only" : "Publicar solo para los usuarios mencionados",
"Unlisted" : "No listado",
"Do not post to public timelines" : "No publicar en líneas de tiempo públicas",
"Followers" : "Seguidores",
"Post to followers only" : "Publicar solo en seguidores",
"Public" : "Público",
"Follow" : "Seguir",
"posts" : "publicaciones",
"following" : "siguiendo"
},"pluralForm" :"nplurals=2; plural=(n != 1);"
}

Wyświetl plik

@ -31,6 +31,8 @@ OC.L10N.register(
"posts" : "julkaisut",
"following" : "seuraa",
"followers" : "seuraajat",
"No results found" : "Tuloksia ei löytynyt",
"There were no results for your search:" : "Hakusi ei palauttanut tuloksia:",
"Searching for" : "Haetaan",
"No posts found" : "Julkaisuja ei löytynyt",
"Posts from people you follow will show up here" : "Seuraamiesi käyttäjien julkaisut näkyvät täällä",
@ -40,6 +42,7 @@ OC.L10N.register(
"Posts from other people on this instance will show up here" : "Muiden ihmisten tähän asennukseen kirjoitetut julkaisut näkyvät täällä",
"No global posts found" : "Yleisiä julkaisuja ei löytynyt",
"Posts from federated instances will show up here" : "Yhteenliitettyihin asennuksiin tehdyt julkaisut näkyvät täällä",
"User not found" : "Käyttäjää ei löytynyt",
"Nextcloud becomes part of the federated social networks!" : "Nextcloudista tulee yhteenliitettyjen sosiaalisten verkostojen osa!",
"We automatically created a Social account for you. Your Social ID is the same as your federated cloud ID:" : "Loimme sinulle automaattisesti Sosiaalinen -tilin. Sinun Social ID on sama kun yhteenliitettyjen pilvien ID:",
"Since you are new to Social, start by following the official Nextcloud account so you don't miss any news" : "Koska olet uusi käyttäjä, aloita seuraamalla virallista Nextcloud -tiliä ettet jää uutisista paitsi",

Wyświetl plik

@ -29,6 +29,8 @@
"posts" : "julkaisut",
"following" : "seuraa",
"followers" : "seuraajat",
"No results found" : "Tuloksia ei löytynyt",
"There were no results for your search:" : "Hakusi ei palauttanut tuloksia:",
"Searching for" : "Haetaan",
"No posts found" : "Julkaisuja ei löytynyt",
"Posts from people you follow will show up here" : "Seuraamiesi käyttäjien julkaisut näkyvät täällä",
@ -38,6 +40,7 @@
"Posts from other people on this instance will show up here" : "Muiden ihmisten tähän asennukseen kirjoitetut julkaisut näkyvät täällä",
"No global posts found" : "Yleisiä julkaisuja ei löytynyt",
"Posts from federated instances will show up here" : "Yhteenliitettyihin asennuksiin tehdyt julkaisut näkyvät täällä",
"User not found" : "Käyttäjää ei löytynyt",
"Nextcloud becomes part of the federated social networks!" : "Nextcloudista tulee yhteenliitettyjen sosiaalisten verkostojen osa!",
"We automatically created a Social account for you. Your Social ID is the same as your federated cloud ID:" : "Loimme sinulle automaattisesti Sosiaalinen -tilin. Sinun Social ID on sama kun yhteenliitettyjen pilvien ID:",
"Since you are new to Social, start by following the official Nextcloud account so you don't miss any news" : "Koska olet uusi käyttäjä, aloita seuraamalla virallista Nextcloud -tiliä ettet jää uutisista paitsi",

Wyświetl plik

@ -20,6 +20,7 @@ OC.L10N.register(
"Post publicly" : "Poster publiquement",
"Post to followers" : "Poster aux abonnés",
"Post to recipients" : "Poster aux destinataires",
"Post unlisted" : "Post non répertorié",
"Direct" : "Direct",
"Post to mentioned users only" : "Poster aux utilisateurs mentionnées seulement",
"Unlisted" : "Non listé",
@ -45,6 +46,7 @@ OC.L10N.register(
"Posts from other people on this instance will show up here" : "Les messages d'autres personnes de cette instance apparaitront ici",
"No global posts found" : "Aucun message global trouvé",
"Posts from federated instances will show up here" : "Les messages des instances fédérées apparaitront ici",
"No posts found for this tag" : "Aucun post trouvé avec cette étiquette",
"User not found" : "Utilisateur non trouvé",
"Sorry, we could not find the account of {userId}" : "Désolé, impossible de trouver le compte {userId}",
"Nextcloud becomes part of the federated social networks!" : "Nextcloud fait maintenant partie des réseaux sociaux fédérés !",

Wyświetl plik

@ -18,6 +18,7 @@
"Post publicly" : "Poster publiquement",
"Post to followers" : "Poster aux abonnés",
"Post to recipients" : "Poster aux destinataires",
"Post unlisted" : "Post non répertorié",
"Direct" : "Direct",
"Post to mentioned users only" : "Poster aux utilisateurs mentionnées seulement",
"Unlisted" : "Non listé",
@ -43,6 +44,7 @@
"Posts from other people on this instance will show up here" : "Les messages d'autres personnes de cette instance apparaitront ici",
"No global posts found" : "Aucun message global trouvé",
"Posts from federated instances will show up here" : "Les messages des instances fédérées apparaitront ici",
"No posts found for this tag" : "Aucun post trouvé avec cette étiquette",
"User not found" : "Utilisateur non trouvé",
"Sorry, we could not find the account of {userId}" : "Désolé, impossible de trouver le compte {userId}",
"Nextcloud becomes part of the federated social networks!" : "Nextcloud fait maintenant partie des réseaux sociaux fédérés !",

Wyświetl plik

@ -35,6 +35,8 @@ OC.L10N.register(
"posts" : "commenti",
"following" : "segui già",
"followers" : "seguaci",
"No results found" : "Nessun risultato trovato",
"There were no results for your search:" : "Non ci sono stati risultati per la tua ricerca:",
"Searching for" : "Ricerca",
"No posts found" : "Nessun commento trovato",
"Posts from people you follow will show up here" : "Commenti da persone che segui saranno mostrati qui",
@ -44,6 +46,7 @@ OC.L10N.register(
"Posts from other people on this instance will show up here" : "Commenti da altre persone su questa istanza saranno mostrati qui",
"No global posts found" : "Nessun commento locale trovato",
"Posts from federated instances will show up here" : "Commenti da istanze federate saranno mostrati qui",
"No posts found for this tag" : "Nessun commento trovato per questa etichetta",
"User not found" : "Utente non trovato",
"Sorry, we could not find the account of {userId}" : "Spiacenti, impossibile trovare l'account di {userId}",
"Nextcloud becomes part of the federated social networks!" : "Nextcloud diventa parte delle reti sociali federate!",

Wyświetl plik

@ -33,6 +33,8 @@
"posts" : "commenti",
"following" : "segui già",
"followers" : "seguaci",
"No results found" : "Nessun risultato trovato",
"There were no results for your search:" : "Non ci sono stati risultati per la tua ricerca:",
"Searching for" : "Ricerca",
"No posts found" : "Nessun commento trovato",
"Posts from people you follow will show up here" : "Commenti da persone che segui saranno mostrati qui",
@ -42,6 +44,7 @@
"Posts from other people on this instance will show up here" : "Commenti da altre persone su questa istanza saranno mostrati qui",
"No global posts found" : "Nessun commento locale trovato",
"Posts from federated instances will show up here" : "Commenti da istanze federate saranno mostrati qui",
"No posts found for this tag" : "Nessun commento trovato per questa etichetta",
"User not found" : "Utente non trovato",
"Sorry, we could not find the account of {userId}" : "Spiacenti, impossibile trovare l'account di {userId}",
"Nextcloud becomes part of the federated social networks!" : "Nextcloud diventa parte delle reti sociali federate!",

Wyświetl plik

@ -35,6 +35,8 @@ OC.L10N.register(
"posts" : "berichten",
"following" : "volgend",
"followers" : "volgers",
"No results found" : "Geen resultaten gevonden",
"There were no results for your search:" : "Geen resultaten voor je zoekterm:",
"Searching for" : "Zoeken naar",
"No posts found" : "Geen berichten gevonden",
"Posts from people you follow will show up here" : "Berichten van mensen die je volgt, worden hier getoond",
@ -44,6 +46,7 @@ OC.L10N.register(
"Posts from other people on this instance will show up here" : "Berichten van anderen op deze server verschijnen hier",
"No global posts found" : "Geen globale berichten gevonden",
"Posts from federated instances will show up here" : "Berichten van gefedereerde servers worden hier getoond",
"No posts found for this tag" : "Geen berichten gevonden met deze tag",
"User not found" : "Gebruiker niet gevonden",
"Sorry, we could not find the account of {userId}" : "Sorry, we konden het account van {userId} niet vinden",
"Nextcloud becomes part of the federated social networks!" : "Nextcloud wordt onderdeel van de gefedereerde sociale netwerken!",

Wyświetl plik

@ -33,6 +33,8 @@
"posts" : "berichten",
"following" : "volgend",
"followers" : "volgers",
"No results found" : "Geen resultaten gevonden",
"There were no results for your search:" : "Geen resultaten voor je zoekterm:",
"Searching for" : "Zoeken naar",
"No posts found" : "Geen berichten gevonden",
"Posts from people you follow will show up here" : "Berichten van mensen die je volgt, worden hier getoond",
@ -42,6 +44,7 @@
"Posts from other people on this instance will show up here" : "Berichten van anderen op deze server verschijnen hier",
"No global posts found" : "Geen globale berichten gevonden",
"Posts from federated instances will show up here" : "Berichten van gefedereerde servers worden hier getoond",
"No posts found for this tag" : "Geen berichten gevonden met deze tag",
"User not found" : "Gebruiker niet gevonden",
"Sorry, we could not find the account of {userId}" : "Sorry, we konden het account van {userId} niet vinden",
"Nextcloud becomes part of the federated social networks!" : "Nextcloud wordt onderdeel van de gefedereerde sociale netwerken!",

Wyświetl plik

@ -6,6 +6,7 @@ OC.L10N.register(
".well-known/webfinger isn't properly set up!" : ".well-known/webfinger није добро подешен!",
"Open documentation" : "Отвори документацију",
"Social app setup" : "Поставке социјалне апликације",
"ActivityPub requires a fixed URL to make entries unique. Note that this can not be changed later without resetting the Social app." : "ActivityPub захтева фиксан URL да би сви уноси били јединствени. Ово се не може изменити накнадно, без да се ресетује цела апликација Социјалних мрежа.",
"ActivityPub URL base" : "ActivityPub URL основа",
"Finish setup" : "Заврши подешавање",
"The Social app needs to be set up by the server administrator." : "Социјалну апликацију мора да подеси администратор сервера.",
@ -32,6 +33,8 @@ OC.L10N.register(
"posts" : "објаве",
"following" : "прати",
"followers" : "пратиоца",
"No results found" : "Нема пронађених резултата",
"There were no results for your search:" : "Нема резултата за претрагу:",
"Searching for" : "Тражим",
"No posts found" : "Нема објава",
"Posts from people you follow will show up here" : "Објаве од људи које пратите ће се појавити овде",
@ -41,6 +44,7 @@ OC.L10N.register(
"Posts from other people on this instance will show up here" : "Објаве од других људи са ове инстанце ће се појављивати овде",
"No global posts found" : "Нема јавних објава",
"Posts from federated instances will show up here" : "Објаве се федерисаних инстанци ће се појавити овде",
"No posts found for this tag" : "Нема нађених објава за ову ознаку",
"User not found" : "Корисник није нађен",
"Sorry, we could not find the account of {userId}" : "Нажалост, не можемо да нађемо налог корисника {userId}",
"Nextcloud becomes part of the federated social networks!" : "Некстклауд је постао део федерисаних социјалних мрежа!",

Wyświetl plik

@ -4,6 +4,7 @@
".well-known/webfinger isn't properly set up!" : ".well-known/webfinger није добро подешен!",
"Open documentation" : "Отвори документацију",
"Social app setup" : "Поставке социјалне апликације",
"ActivityPub requires a fixed URL to make entries unique. Note that this can not be changed later without resetting the Social app." : "ActivityPub захтева фиксан URL да би сви уноси били јединствени. Ово се не може изменити накнадно, без да се ресетује цела апликација Социјалних мрежа.",
"ActivityPub URL base" : "ActivityPub URL основа",
"Finish setup" : "Заврши подешавање",
"The Social app needs to be set up by the server administrator." : "Социјалну апликацију мора да подеси администратор сервера.",
@ -30,6 +31,8 @@
"posts" : "објаве",
"following" : "прати",
"followers" : "пратиоца",
"No results found" : "Нема пронађених резултата",
"There were no results for your search:" : "Нема резултата за претрагу:",
"Searching for" : "Тражим",
"No posts found" : "Нема објава",
"Posts from people you follow will show up here" : "Објаве од људи које пратите ће се појавити овде",
@ -39,6 +42,7 @@
"Posts from other people on this instance will show up here" : "Објаве од других људи са ове инстанце ће се појављивати овде",
"No global posts found" : "Нема јавних објава",
"Posts from federated instances will show up here" : "Објаве се федерисаних инстанци ће се појавити овде",
"No posts found for this tag" : "Нема нађених објава за ову ознаку",
"User not found" : "Корисник није нађен",
"Sorry, we could not find the account of {userId}" : "Нажалост, не можемо да нађемо налог корисника {userId}",
"Nextcloud becomes part of the federated social networks!" : "Некстклауд је постао део федерисаних социјалних мрежа!",

Wyświetl plik

@ -35,6 +35,8 @@ OC.L10N.register(
"posts" : "ileti",
"following" : "takip edilenler",
"followers" : "takip edenler",
"No results found" : "Herhangi bir sonuç bulunamadı",
"There were no results for your search:" : "Aramanızdan bir sonuç alınamadı:",
"Searching for" : "Şu ifade aranıyor",
"No posts found" : "Herhangi bir ileti bulunamadı",
"Posts from people you follow will show up here" : "Takip ettiğiniz kişilerin iletileri burada görüntülenir",
@ -44,6 +46,7 @@ OC.L10N.register(
"Posts from other people on this instance will show up here" : "Bu sunucuyu kullanan diğer kişilerin gönderdiği iletiler burada görüntülenir",
"No global posts found" : "Herhangi bir genel ileti bulunamadı",
"Posts from federated instances will show up here" : "Birleşmiş sunuculara gönderilmiş iletiler burada görüntülenir",
"No posts found for this tag" : "Bu etiketi taşıyan bir ileti bulunamadı",
"User not found" : "Kullanıcı bulunamadı",
"Sorry, we could not find the account of {userId}" : "Maalesef, {userId} hesabını bulamadık",
"Nextcloud becomes part of the federated social networks!" : "Nextcloud birleşmiş sosyal ağların bir parçası haline geliyor!",

Wyświetl plik

@ -33,6 +33,8 @@
"posts" : "ileti",
"following" : "takip edilenler",
"followers" : "takip edenler",
"No results found" : "Herhangi bir sonuç bulunamadı",
"There were no results for your search:" : "Aramanızdan bir sonuç alınamadı:",
"Searching for" : "Şu ifade aranıyor",
"No posts found" : "Herhangi bir ileti bulunamadı",
"Posts from people you follow will show up here" : "Takip ettiğiniz kişilerin iletileri burada görüntülenir",
@ -42,6 +44,7 @@
"Posts from other people on this instance will show up here" : "Bu sunucuyu kullanan diğer kişilerin gönderdiği iletiler burada görüntülenir",
"No global posts found" : "Herhangi bir genel ileti bulunamadı",
"Posts from federated instances will show up here" : "Birleşmiş sunuculara gönderilmiş iletiler burada görüntülenir",
"No posts found for this tag" : "Bu etiketi taşıyan bir ileti bulunamadı",
"User not found" : "Kullanıcı bulunamadı",
"Sorry, we could not find the account of {userId}" : "Maalesef, {userId} hesabını bulamadık",
"Nextcloud becomes part of the federated social networks!" : "Nextcloud birleşmiş sosyal ağların bir parçası haline geliyor!",

Wyświetl plik

@ -76,7 +76,7 @@ class CacheRefresh extends Base {
* @param MiscService $miscService
*/
public function __construct(
AccountService $actorService, CacheActorService $cacheActorService,
AccountService $accountService, CacheActorService $cacheActorService,
DocumentService $documentService, HashtagService $hashtagService,
ConfigService $configService, MiscService $miscService
) {

Wyświetl plik

@ -0,0 +1,188 @@
<?php
declare(strict_types=1);
/**
* Nextcloud - Social Support
*
* This file is licensed under the Affero General Public License version 3 or
* later. See the COPYING file.
*
* @author Maxence Lange <maxence@artificial-owl.com>
* @copyright 2018, Maxence Lange <maxence@artificial-owl.com>
* @license GNU AGPL version 3 or any later version
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as
* published by the Free Software Foundation, either version 3 of the
* License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
namespace OCA\Social\Controller;
use daita\MySmallPhpTools\Exceptions\ArrayNotFoundException;
use daita\MySmallPhpTools\Traits\Nextcloud\TNCDataResponse;
use daita\MySmallPhpTools\Traits\TArrayTools;
use Exception;
use OCA\Social\AppInfo\Application;
use OCA\Social\Exceptions\RetrieveAccountFormatException;
use OCA\Social\Service\AccountService;
use OCA\Social\Service\CacheActorService;
use OCA\Social\Service\CurlService;
use OCA\Social\Service\MiscService;
use OCP\AppFramework\Controller;
use OCP\AppFramework\Http\Response;
use OCP\AppFramework\Http\TemplateResponse;
use OCP\IRequest;
use OCP\IUserManager;
use OCP\IUserSession;
class OStatusController extends Controller {
use TNCDataResponse;
use TArrayTools;
/** @var CacheActorService */
private $cacheActorService;
/** @var AccountService */
private $accountService;
/** @var CurlService */
private $curlService;
/** @var MiscService */
private $miscService;
/** @var IUserManager */
private $userSession;
/**
* OStatusController constructor.
*
* @param IRequest $request
* @param CacheActorService $cacheActorService
* @param AccountService $accountService
* @param CurlService $curlService
* @param MiscService $miscService
*/
public function __construct(
IRequest $request, CacheActorService $cacheActorService, AccountService $accountService,
CurlService $curlService, MiscService $miscService, IUserSession $userSession
) {
parent::__construct(Application::APP_NAME, $request);
$this->cacheActorService = $cacheActorService;
$this->accountService = $accountService;
$this->curlService = $curlService;
$this->miscService = $miscService;
$this->userSession = $userSession;
}
/**
* @NoCSRFRequired
* @NoAdminRequired
*
* @param string $uri
*
* @return Response
*/
public function subscribe(string $uri): Response {
try {
$actor = $this->cacheActorService->getFromAccount($uri);
$user = $this->userSession->getUser();
if ($user === null) {
return $this->fail('Failed to retrieve current user');
}
return new TemplateResponse('social', 'ostatus', [
'serverData' => [
'account' => $actor->getAccount(),
'currentUser' => [
'uid' => $user->getUID(),
'displayName' => $user->getDisplayName(),
]
]
], 'guest');
} catch (Exception $e) {
return $this->fail($e);
}
}
/**
* @NoCSRFRequired
* @NoAdminRequired
* @PublicPage
*
* @param string $local
* @return Response
*/
public function followRemote(string $local): Response {
try {
$following = $this->accountService->getActor($local);
return new TemplateResponse('social', 'ostatus', [
'serverData' => [
'local' => $local,
'account' => $following->getAccount()
]
], 'guest');
} catch (\Exception $e) {
return $this->fail($e);
}
}
/**
* @NoCSRFRequired
* @NoAdminRequired
* @PublicPage
*
* @param string $local
* @param string $account
*
* @return Response
*/
public function getLink(string $local, string $account): Response {
try {
$following = $this->accountService->getActor($local);
$result = $this->curlService->webfingerAccount($account);
try {
$link = $this->extractArray(
'rel', 'http://ostatus.org/schema/1.0/subscribe',
$this->getArray('links', $result)
);
} catch (ArrayNotFoundException $e) {
throw new RetrieveAccountFormatException();
}
$template = $this->get('template', $link, '');
$url = str_replace('{uri}', $following->getAccount(), $template);
return $this->success(['url' => $url]);
} catch (Exception $e) {
return $this->fail($e);
}
}
}

Wyświetl plik

@ -32,6 +32,7 @@ namespace OCA\Social\Model\ActivityPub;
use daita\MySmallPhpTools\Traits\TArrayTools;
use daita\MySmallPhpTools\Traits\TPathTools;
use daita\MySmallPhpTools\Traits\TStringTools;
use JsonSerializable;
use OCA\Social\Exceptions\ActivityCantBeVerifiedException;
use OCA\Social\Exceptions\InvalidOriginException;
@ -45,6 +46,7 @@ class ACore extends Item implements JsonSerializable {
use TArrayTools;
use TStringTools;
use TPathTools;
@ -238,11 +240,7 @@ class ACore extends Item implements JsonSerializable {
$base = $this->withoutEndSlash($this->withBeginSlash($base));
}
$uuid = sprintf(
'%04x%04x-%04x-%04x-%04x-%04x%04x%04x', mt_rand(0, 0xffff), mt_rand(0, 0xffff),
mt_rand(0, 0xffff), mt_rand(0, 0xfff) | 0x4000, mt_rand(0, 0x3fff) | 0x8000,
mt_rand(0, 0xffff), mt_rand(0, 0xffff), mt_rand(0, 0xffff)
);
$uuid = $this->uuid();
$this->setId($url . $base . '/' . $uuid);
}

Wyświetl plik

@ -32,6 +32,7 @@ namespace OCA\Social\Model;
use daita\MySmallPhpTools\Traits\TArrayTools;
use daita\MySmallPhpTools\Traits\TStringTools;
use DateTime;
use JsonSerializable;
@ -45,6 +46,7 @@ class RequestQueue implements JsonSerializable {
use TArrayTools;
use TStringTools;
const STATUS_STANDBY = 0;
@ -162,11 +164,7 @@ class RequestQueue implements JsonSerializable {
* @return RequestQueue
*/
public function resetToken(): RequestQueue {
$uuid = sprintf(
'%04x%04x-%04x-%04x-%04x-%04x%04x%04x', mt_rand(0, 0xffff), mt_rand(0, 0xffff),
mt_rand(0, 0xffff), mt_rand(0, 0xfff) | 0x4000, mt_rand(0, 0x3fff) | 0x8000,
mt_rand(0, 0xffff), mt_rand(0, 0xffff), mt_rand(0, 0xffff)
);
$uuid = $this->uuid();
$this->setToken($uuid);

Wyświetl plik

@ -161,6 +161,7 @@ class AccountService {
* @throws NoUserException
* @throws SocialAppConfigException
* @throws UrlCloudException
* @throws ItemUnknownException
*/
public function getActorFromUserId(string $userId, bool $create = false): Person {
$this->miscService->confirmUserId($userId);

Wyświetl plik

@ -33,6 +33,7 @@ namespace OCA\Social\Service;
use daita\MySmallPhpTools\Exceptions\MalformedArrayException;
use daita\MySmallPhpTools\Model\Request;
use daita\MySmallPhpTools\Traits\TArrayTools;
use daita\MySmallPhpTools\Traits\TStringTools;
use Exception;
use OCA\Social\Exceptions\CacheContentException;
use OCA\Social\Exceptions\CacheContentMimeTypeException;
@ -52,6 +53,7 @@ class CacheDocumentService {
use TArrayTools;
use TStringTools;
/** @var IAppData */
@ -103,11 +105,7 @@ class CacheDocumentService {
*/
public function saveRemoteFileToCache(string $url, &$mime = '') {
$filename = sprintf(
'%04x%04x-%04x-%04x-%04x-%04x%04x%04x', mt_rand(0, 0xffff), mt_rand(0, 0xffff),
mt_rand(0, 0xffff), mt_rand(0, 0xfff) | 0x4000, mt_rand(0, 0x3fff) | 0x8000,
mt_rand(0, 0xffff), mt_rand(0, 0xffff), mt_rand(0, 0xffff)
);
$filename = $this->uuid();
// creating a path aa/bb/cc/dd/ from the filename aabbccdd-0123-[...]
$path = chunk_split(substr($filename, 0, 8), 2, '/');

Wyświetl plik

@ -90,21 +90,15 @@ class CurlService {
/**
* @param string $account
*
* @return Person
* @throws InvalidOriginException
* @return array
* @throws InvalidResourceException
* @throws MalformedArrayException
* @throws RedundancyLimitException
* @throws RequestContentException
* @throws RetrieveAccountFormatException
* @throws RequestNetworkException
* @throws RequestResultSizeException
* @throws RequestServerException
* @throws SocialAppConfigException
* @throws ItemUnknownException
* @throws RequestResultNotJsonException
*/
public function retrieveAccount(string $account): Person {
public function webfingerAccount(string $account): array {
$account = $this->withoutBeginAt($account);
// we consider an account is like an email
@ -122,6 +116,29 @@ class CurlService {
$request->setAddress($host);
$result = $this->request($request);
return $result;
}
/**
* @param string $account
*
* @return Person
* @throws InvalidOriginException
* @throws InvalidResourceException
* @throws MalformedArrayException
* @throws RedundancyLimitException
* @throws RequestContentException
* @throws RetrieveAccountFormatException
* @throws RequestNetworkException
* @throws RequestResultSizeException
* @throws RequestServerException
* @throws SocialAppConfigException
* @throws ItemUnknownException
*/
public function retrieveAccount(string $account): Person {
$result = $this->webfingerAccount($account);
try {
$link = $this->extractArray('rel', 'self', $this->getArray('links', $result));
} catch (ArrayNotFoundException $e) {

Wyświetl plik

@ -83,6 +83,11 @@ $finger = [
'rel' => 'self',
'type' => 'application/activity+json',
'href' => $href
],
[
'rel' => 'http://ostatus.org/schema/1.0/subscribe',
'template' => urldecode(
$href = $urlGenerator->linkToRouteAbsolute('social.OStatus.subscribe', ['uri' => '{uri}']))
]
]
];

23983
package-lock.json wygenerowano

Plik diff jest za duży Load Diff

Wyświetl plik

@ -29,18 +29,18 @@
"dependencies": {
"linkifyjs": "^2.1.8",
"nextcloud-axios": "^0.1.3",
"nextcloud-vue": "^0.6.1",
"nextcloud-vue": "^0.6.3",
"tributejs": "^3.5.3",
"twemoji": "^11.3.0",
"uuid": "^3.3.2",
"v-tooltip": "^2.0.0-rc.33",
"vue": "^2.5.22",
"vue": "^2.6.6",
"vue-click-outside": "^1.0.7",
"vue-contenteditable-directive": "^1.2.0",
"vue-emoji-picker": "^1.0.1",
"vue-infinite-loading": "^2.4.3",
"vue-router": "^3.0.2",
"vue-tribute": "^1.0.1",
"vue-tribute": "^1.0.2",
"vue-twemoji": "^1.0.1",
"vuex": "^3.1.0",
"vuetrend": "^0.3.2",
@ -54,16 +54,16 @@
"node": ">=10.0.0"
},
"devDependencies": {
"@babel/core": "^7.2.2",
"@babel/core": "^7.3.3",
"@babel/plugin-syntax-dynamic-import": "^7.2.0",
"@babel/preset-env": "^7.3.1",
"@vue/test-utils": "^1.0.0-beta.29",
"acorn": "^6.0.7",
"acorn": "^6.1.0",
"babel-eslint": "^10.0.1",
"babel-jest": "^24.0.0",
"babel-loader": "^8.0.5",
"css-loader": "^2.1.0",
"eslint": "^5.13.0",
"eslint": "^5.14.1",
"eslint-config-standard": "^12.0.0",
"eslint-friendly-formatter": "^4.0.1",
"eslint-loader": "^2.1.1",
@ -71,7 +71,7 @@
"eslint-plugin-node": "^8.0.1",
"eslint-plugin-promise": "^4.0.1",
"eslint-plugin-standard": "^4.0.0",
"eslint-plugin-vue": "^5.1.0",
"eslint-plugin-vue": "^5.2.2",
"file-loader": "^3.0.1",
"jest": "^24.0.0",
"jest-serializer-vue": "^2.0.2",
@ -82,11 +82,11 @@
"stylelint": "^8.4.0",
"stylelint-config-recommended-scss": "^3.2.0",
"stylelint-webpack-plugin": "^0.10.5",
"vue-jest": "^3.0.2",
"vue-loader": "^15.6.2",
"vue-jest": "^3.0.3",
"vue-loader": "^15.6.3",
"vue-style-loader": "^4.1.1",
"vue-template-compiler": "^2.5.22",
"webpack": "^4.29.1",
"vue-template-compiler": "^2.6.6",
"webpack": "^4.29.5",
"webpack-cli": "^3.2.3",
"webpack-merge": "^4.2.1"
},

Wyświetl plik

@ -35,6 +35,9 @@
</a>
</p>
<follow-button :account="accountInfo.account" />
<button v-if="serverData.public" class="primary" @click="followRemote">
{{ t('social', 'Follow') }}
</button>
</div>
<!-- TODO: we have no details, timeline and follower list for non-local accounts for now -->
<ul v-if="accountInfo.details && accountInfo.local" class="user-profile--sections">
@ -145,7 +148,9 @@ export default {
}
},
methods: {
followRemote() {
window.open(OC.generateUrl('/apps/social/api/v1/ostatus/followRemote/' + encodeURI(this.uid)), 'followRemote', 'width=433,height=600toolbar=no,menubar=no,scrollbars=yes,resizable=yes')
}
}
}

41
src/ostatus.js 100644
Wyświetl plik

@ -0,0 +1,41 @@
/*
* @copyright Copyright (c) 2019 Julius Härtl <jus@bitgrid.net>
*
* @author Julius Härtl <jus@bitgrid.net>
*
* @license GNU AGPL version 3 or any later version
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as
* published by the Free Software Foundation, either version 3 of the
* License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
import Vue from 'vue'
import store from './store'
import OStatus from './views/OStatus'
// eslint-disable-next-line
__webpack_nonce__ = btoa(OC.requestToken)
// eslint-disable-next-line
__webpack_public_path__ = OC.linkTo('social', 'js/')
Vue.prototype.t = t
Vue.prototype.n = n
Vue.prototype.OC = OC
Vue.prototype.OCA = OCA
/* eslint-disable-next-line no-new */
new Vue({
render: h => h(OStatus),
store: store
}).$mount('#vue-content')

Wyświetl plik

@ -0,0 +1,135 @@
<template>
<div v-if="accountInfo">
<div v-if="!serverData.local">
<h2>{{ t('social', 'Follow on Nextcloud Social') }}</h2>
<p>{{ t('social', 'Hello') }} <avatar :user="currentUser.uid" :size="16" />{{ currentUser.displayName }}</p>
<p v-if="!isFollowing">
{{ t('social', 'Please confirm that you want to follow this account:') }}
</p>
<avatar :url="avatarUrl" :disable-tooltip="true" :size="128" />
<h2>{{ displayName }}</h2>
<form v-if="!isFollowing" @submit.prevent="follow">
<input type="submit" class="primary" value="Follow">
</form>
<p v-else>
<span class="icon icon-checkmark-white" />
{{ t('social', 'You are following this account') }}
</p>
<div v-if="isFollowing">
<button @click="close">
{{ t('social', 'Close') }}
</button>
</div>
</div>
<div v-if="serverData.local">
<p>{{ t('social', 'You are going to follow:') }}</p>
<avatar :user="serverData.local" :disable-tooltip="true" :size="128" />
<h2>{{ displayName }}</h2>
<form @submit.prevent="followRemote">
<input v-model="remote" type="text" :placeholder="t('social', 'name@domain of your federation account')">
<input type="submit" class="primary" :value="t('social', 'Continue')">
</form>
<p>{{ t('social', 'This step is needed as the user is probably not registered on the same server as you are. We will redirect you to your homeserver to follow this account.') }}</p>
</div>
</div>
<div v-else :class="{ 'icon-loading-dark': !accountInfo }" />
</template>
<style scoped>
h2, p {
color: var(--color-primary-text);
}
p .icon {
display: inline-block;
}
.avatardiv {
vertical-align: -4px;
margin-right: 3px;
filter: drop-shadow(0 0 0.5rem #333);
margin-top: 10px;
margin-bottom: 20px;
}
</style>
<style>
.wrapper {
margin-top: 20px;
}
</style>
<script>
import { Avatar } from 'nextcloud-vue'
import axios from 'nextcloud-axios'
import currentuserMixin from './../mixins/currentUserMixin'
export default {
name: 'App',
components: {
Avatar
},
mixins: [currentuserMixin],
data() {
return {
remote: ''
}
},
computed: {
isFollowing() {
return this.$store.getters.isFollowingUser(this.account)
},
account() {
return this.serverData.account
},
avatarUrl() {
return OC.generateUrl('/apps/social/api/v1/global/actor/avatar?id=' + this.accountInfo.id)
},
accountInfo: function() {
return this.$store.getters.getAccount(this.serverData.account)
},
currentUser() {
return window.oc_current_user
},
displayName() {
if (typeof this.accountInfo.name !== 'undefined' && this.accountInfo.name !== '') {
return this.accountInfo.name
}
return this.account
}
},
beforeMount: function() {
// importing server data into the store
const serverDataElmt = document.getElementById('serverData')
if (serverDataElmt !== null) {
const serverData = JSON.parse(document.getElementById('serverData').dataset.server)
if (serverData.currentUser) {
window.oc_current_user = JSON.parse(JSON.stringify(serverData.currentUser))
}
this.$store.commit('setServerData', serverData)
if (this.serverData.account && !this.serverData.local) {
this.$store.dispatch('fetchAccountInfo', this.serverData.account)
}
if (this.serverData.local) {
this.$store.dispatch('fetchPublicAccountInfo', this.serverData.local)
}
}
},
methods: {
follow() {
this.$store.dispatch('followAccount', { currentAccount: this.cloudId, accountToFollow: this.account }).then(() => {
})
},
followRemote() {
axios.get(OC.generateUrl(`/apps/social/api/v1/ostatus/link/${this.serverData.local}/` + encodeURI(this.remote))).then((a) => {
window.location = a.data.result.url
})
},
close() {
window.close()
}
}
}
</script>

Wyświetl plik

@ -0,0 +1,28 @@
<?php
/**
* @copyright Copyright (c) 2019 Julius Härtl <jus@bitgrid.net>
*
* @author Julius Härtl <jus@bitgrid.net>
*
* @license GNU AGPL version 3 or any later version
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as
* published by the Free Software Foundation, either version 3 of the
* License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
script('social', 'ostatus');
style('social', 'style');
?>
<span id="serverData" data-server="<?php p(json_encode($_['serverData']));?>"></span>
<div id="vue-content"></div>

Wyświetl plik

@ -3,11 +3,14 @@ const VueLoaderPlugin = require('vue-loader/lib/plugin');
module.exports = {
entry: path.join(__dirname, 'src', 'main.js'),
entry: {
social: path.join(__dirname, 'src', 'main.js'),
ostatus: path.join(__dirname, 'src', 'ostatus.js'),
},
output: {
path: path.resolve(__dirname, './js'),
publicPath: '/js/',
filename: 'social.js',
filename: '[name].js',
chunkFilename: '[name].[chunkhash].js'
},
module: {