4 use Shaarli\Api\Exceptions\ApiAuthorizationException
;
5 use Shaarli\Bookmark\Bookmark
;
6 use Shaarli\Http\Base64Url
;
14 * Validates a JWT token authenticity.
16 * @param string $token JWT token extracted from the headers.
17 * @param string $secret API secret set in the settings.
19 * @return bool true on success
21 * @throws ApiAuthorizationException the token is not valid.
23 public static function validateJwtToken($token, $secret)
25 $parts = explode('.', $token);
26 if (count($parts) != 3 || strlen($parts[0]) == 0 || strlen($parts[1]) == 0) {
27 throw new ApiAuthorizationException('Malformed JWT token');
30 $genSign = Base64Url
::encode(hash_hmac('sha512', $parts[0] .'.'. $parts[1], $secret, true));
31 if ($parts[2] != $genSign) {
32 throw new ApiAuthorizationException('Invalid JWT signature');
35 $header = json_decode(Base64Url
::decode($parts[0]));
36 if ($header === null) {
37 throw new ApiAuthorizationException('Invalid JWT header');
40 $payload = json_decode(Base64Url
::decode($parts[1]));
41 if ($payload === null) {
42 throw new ApiAuthorizationException('Invalid JWT payload');
45 if (empty($payload->iat
)
46 || $payload->iat
> time()
47 || time() - $payload->iat
> ApiMiddleware
::$TOKEN_DURATION
49 throw new ApiAuthorizationException('Invalid JWT issued time');
56 * Format a Link for the REST API.
58 * @param Bookmark $bookmark Bookmark data read from the datastore.
59 * @param string $indexUrl Shaarli's index URL (used for relative URL).
61 * @return array Link data formatted for the REST API.
63 public static function formatLink($bookmark, $indexUrl)
65 $out['id'] = $bookmark->getId();
66 // Not an internal link
67 if (! $bookmark->isNote()) {
68 $out['url'] = $bookmark->getUrl();
70 $out['url'] = rtrim($indexUrl, '/') . '/' . ltrim($bookmark->getUrl(), '/');
72 $out['shorturl'] = $bookmark->getShortUrl();
73 $out['title'] = $bookmark->getTitle();
74 $out['description'] = $bookmark->getDescription();
75 $out['tags'] = $bookmark->getTags();
76 $out['private'] = $bookmark->isPrivate();
77 $out['created'] = $bookmark->getCreated()->format(\DateTime
::ATOM
);
78 if (! empty($bookmark->getUpdated())) {
79 $out['updated'] = $bookmark->getUpdated()->format(\DateTime
::ATOM
);
87 * Convert a link given through a request, to a valid Bookmark for the datastore.
89 * If no URL is provided, it will generate a local note URL.
90 * If no title is provided, it will use the URL as title.
92 * @param array $input Request Link.
93 * @param bool $defaultPrivate Request Link.
95 * @return Bookmark instance.
97 public static function buildLinkFromRequest($input, $defaultPrivate)
99 $bookmark = new Bookmark();
100 $url = ! empty($input['url']) ? cleanup_url($input['url']) : '';
101 if (isset($input['private'])) {
102 $private = filter_var($input['private'], FILTER_VALIDATE_BOOLEAN
);
104 $private = $defaultPrivate;
107 $bookmark->setTitle(! empty($input['title']) ? $input['title'] : '');
108 $bookmark->setUrl($url);
109 $bookmark->setDescription(! empty($input['description']) ? $input['description'] : '');
110 $bookmark->setTags(! empty($input['tags']) ? $input['tags'] : []);
111 $bookmark->setPrivate($private);
117 * Update link fields using an updated link object.
119 * @param Bookmark $oldLink data
120 * @param Bookmark $newLink data
122 * @return Bookmark $oldLink updated with $newLink values
124 public static function updateLink($oldLink, $newLink)
126 $oldLink->setTitle($newLink->getTitle());
127 $oldLink->setUrl($newLink->getUrl());
128 $oldLink->setDescription($newLink->getDescription());
129 $oldLink->setTags($newLink->getTags());
130 $oldLink->setPrivate($newLink->isPrivate());
136 * Format a Tag for the REST API.
138 * @param string $tag Tag name
139 * @param int $occurrences Number of bookmarks using this tag
141 * @return array Link data formatted for the REST API.
143 public static function formatTag($tag, $occurences)
147 'occurrences' => $occurences,