mirror of
https://github.com/shlinkio/shlink.git
synced 2026-03-03 05:33:11 +08:00
Compare commits
15 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
ea6e0d7c7f | ||
|
|
d9d599eab4 | ||
|
|
d1ba44e1b3 | ||
|
|
dff2ad3740 | ||
|
|
f7e63710e4 | ||
|
|
d3b5cd5c57 | ||
|
|
86ed83d25e | ||
|
|
f96d0fe30a | ||
|
|
be406bd676 | ||
|
|
044278752b | ||
|
|
343d2ab44a | ||
|
|
66992f644e | ||
|
|
cf245524dd | ||
|
|
ad520811a3 | ||
|
|
ee1e1d5688 |
10
CHANGELOG.md
10
CHANGELOG.md
@@ -1,5 +1,15 @@
|
||||
## CHANGELOG
|
||||
|
||||
### 1.7.1
|
||||
|
||||
**Enhancements:**
|
||||
|
||||
* [128: Upgrade to expressive 2.2](https://github.com/shlinkio/shlink/issues/128)
|
||||
|
||||
**Bugs**
|
||||
|
||||
* [126: Expressive 2.2 causes failures by triggering E_USER_DEPRECATED errors](https://github.com/shlinkio/shlink/issues/126)
|
||||
|
||||
### 1.7.0
|
||||
|
||||
**Features**
|
||||
|
||||
@@ -29,7 +29,7 @@ return [
|
||||
|
||||
'routing' => [
|
||||
'middleware' => [
|
||||
Expressive\Application::ROUTING_MIDDLEWARE,
|
||||
Expressive\Router\Middleware\RouteMiddleware::class,
|
||||
],
|
||||
'priority' => 10,
|
||||
],
|
||||
@@ -38,7 +38,7 @@ return [
|
||||
'path' => '/rest',
|
||||
'middleware' => [
|
||||
CrossDomainMiddleware::class,
|
||||
Expressive\Middleware\ImplicitOptionsMiddleware::class,
|
||||
Expressive\Router\Middleware\ImplicitOptionsMiddleware::class,
|
||||
BodyParserMiddleware::class,
|
||||
CheckAuthenticationMiddleware::class,
|
||||
],
|
||||
@@ -47,7 +47,7 @@ return [
|
||||
|
||||
'post-routing' => [
|
||||
'middleware' => [
|
||||
Expressive\Application::DISPATCH_MIDDLEWARE,
|
||||
Expressive\Router\Middleware\DispatchMiddleware::class,
|
||||
],
|
||||
'priority' => 1,
|
||||
],
|
||||
|
||||
@@ -18,6 +18,8 @@ use Zend\ConfigAggregator;
|
||||
*/
|
||||
|
||||
return (new ConfigAggregator\ConfigAggregator([
|
||||
Zend\Expressive\ConfigProvider::class,
|
||||
Zend\Expressive\Router\ConfigProvider::class,
|
||||
ExpressiveErrorHandler\ConfigProvider::class,
|
||||
Common\ConfigProvider::class,
|
||||
Core\ConfigProvider::class,
|
||||
|
||||
@@ -1,7 +0,0 @@
|
||||
{
|
||||
"name": "Authorization",
|
||||
"in": "header",
|
||||
"description": "The authorization token with Bearer type",
|
||||
"required": true,
|
||||
"type": "string"
|
||||
}
|
||||
@@ -5,24 +5,39 @@
|
||||
],
|
||||
"summary": "Perform authentication",
|
||||
"description": "Performs an authentication",
|
||||
"parameters": [
|
||||
{
|
||||
"name": "apiKey",
|
||||
"in": "formData",
|
||||
"description": "The API key to authenticate with",
|
||||
"required": true,
|
||||
"type": "string"
|
||||
"requestBody": {
|
||||
"description": "Request body.",
|
||||
"required": true,
|
||||
"content": {
|
||||
"application/json": {
|
||||
"schema": {
|
||||
"type": "object",
|
||||
"required": [
|
||||
"apiKey"
|
||||
],
|
||||
"properties": {
|
||||
"apiKey": {
|
||||
"description": "The API key to authenticate with",
|
||||
"type": "string"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
],
|
||||
},
|
||||
"responses": {
|
||||
"200": {
|
||||
"description": "The authentication worked.",
|
||||
"schema": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"token": {
|
||||
"type": "string",
|
||||
"description": "The authentication token that needs to be sent in the Authorization header"
|
||||
"content": {
|
||||
"application/json": {
|
||||
"schema": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"token": {
|
||||
"type": "string",
|
||||
"description": "The authentication token that needs to be sent in the Authorization header"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
@@ -34,20 +49,32 @@
|
||||
},
|
||||
"400": {
|
||||
"description": "An API key was not provided.",
|
||||
"schema": {
|
||||
"$ref": "../definitions/Error.json"
|
||||
"content": {
|
||||
"application/json": {
|
||||
"schema": {
|
||||
"$ref": "../definitions/Error.json"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"401": {
|
||||
"description": "The API key is incorrect, is disabled or has expired.",
|
||||
"schema": {
|
||||
"$ref": "../definitions/Error.json"
|
||||
"content": {
|
||||
"application/json": {
|
||||
"schema": {
|
||||
"$ref": "../definitions/Error.json"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"500": {
|
||||
"description": "Unexpected error.",
|
||||
"schema": {
|
||||
"$ref": "../definitions/Error.json"
|
||||
"content": {
|
||||
"application/json": {
|
||||
"schema": {
|
||||
"$ref": "../definitions/Error.json"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -11,59 +11,73 @@
|
||||
"in": "query",
|
||||
"description": "The page to be displayed. Defaults to 1",
|
||||
"required": false,
|
||||
"type": "integer"
|
||||
"schema": {
|
||||
"type": "integer"
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "searchTerm",
|
||||
"in": "query",
|
||||
"description": "A query used to filter results by searching for it on the longUrl and shortCode fields. (Since v1.3.0)",
|
||||
"required": false,
|
||||
"type": "string"
|
||||
"schema": {
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "tags",
|
||||
"in": "query",
|
||||
"description": "A list of tags used to filter the resultset. Only short URLs tagged with at least one of the provided tags will be returned. (Since v1.3.0)",
|
||||
"required": false,
|
||||
"type": "array",
|
||||
"items": {
|
||||
"type": "string"
|
||||
"schema": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"type": "string"
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "orderBy",
|
||||
"in": "query",
|
||||
"description": "The field from which you want to order the result. (Since v1.3.0)",
|
||||
"enum": [
|
||||
"originalUrl",
|
||||
"shortCode",
|
||||
"dateCreated",
|
||||
"visits"
|
||||
],
|
||||
"required": false,
|
||||
"type": "string"
|
||||
},
|
||||
"schema": {
|
||||
"type": "string",
|
||||
"enum": [
|
||||
"originalUrl",
|
||||
"shortCode",
|
||||
"dateCreated",
|
||||
"visits"
|
||||
]
|
||||
}
|
||||
}
|
||||
],
|
||||
"security": [
|
||||
{
|
||||
"$ref": "../parameters/Authorization.json"
|
||||
"Bearer": []
|
||||
}
|
||||
],
|
||||
"responses": {
|
||||
"200": {
|
||||
"description": "The list of short URLs",
|
||||
"schema": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"shortUrls": {
|
||||
"content": {
|
||||
"application/json": {
|
||||
"schema": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"data": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"$ref": "../definitions/ShortUrl.json"
|
||||
"shortUrls": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"data": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"$ref": "../definitions/ShortUrl.json"
|
||||
}
|
||||
},
|
||||
"pagination": {
|
||||
"$ref": "../definitions/Pagination.json"
|
||||
}
|
||||
}
|
||||
},
|
||||
"pagination": {
|
||||
"$ref": "../definitions/Pagination.json"
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -110,8 +124,12 @@
|
||||
},
|
||||
"500": {
|
||||
"description": "Unexpected error.",
|
||||
"schema": {
|
||||
"$ref": "../definitions/Error.json"
|
||||
"content": {
|
||||
"application/json": {
|
||||
"schema": {
|
||||
"$ref": "../definitions/Error.json"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -123,87 +141,97 @@
|
||||
],
|
||||
"summary": "Create short URL",
|
||||
"description": "Creates a new short code",
|
||||
"parameters": [
|
||||
"security": [
|
||||
{
|
||||
"name": "longUrl",
|
||||
"in": "formData",
|
||||
"description": "The URL to parse",
|
||||
"required": true,
|
||||
"type": "string"
|
||||
},
|
||||
{
|
||||
"name": "tags",
|
||||
"in": "formData",
|
||||
"description": "The URL to parse",
|
||||
"required": false,
|
||||
"type": "array",
|
||||
"items": {
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "validSince",
|
||||
"in": "formData",
|
||||
"description": "The date (in ISO-8601 format) from which this short code will be valid",
|
||||
"required": false,
|
||||
"type": "string"
|
||||
},
|
||||
{
|
||||
"name": "validUntil",
|
||||
"in": "formData",
|
||||
"description": "The date (in ISO-8601 format) until which this short code will be valid",
|
||||
"required": false,
|
||||
"type": "string"
|
||||
},
|
||||
{
|
||||
"name": "customSlug",
|
||||
"in": "formData",
|
||||
"description": "A unique custom slug to be used instead of the generated short code",
|
||||
"required": false,
|
||||
"type": "string"
|
||||
},
|
||||
{
|
||||
"name": "maxVisits",
|
||||
"in": "formData",
|
||||
"description": "The maximum number of allowed visits for this short code",
|
||||
"required": false,
|
||||
"type": "number"
|
||||
},
|
||||
{
|
||||
"$ref": "../parameters/Authorization.json"
|
||||
"Bearer": []
|
||||
}
|
||||
],
|
||||
"requestBody": {
|
||||
"description": "Request body.",
|
||||
"required": true,
|
||||
"content": {
|
||||
"application/json": {
|
||||
"schema": {
|
||||
"type": "object",
|
||||
"required": [
|
||||
"longUrl"
|
||||
],
|
||||
"properties": {
|
||||
"longUrl": {
|
||||
"description": "The URL to parse",
|
||||
"type": "string"
|
||||
},
|
||||
"tags": {
|
||||
"description": "The URL to parse",
|
||||
"type": "array",
|
||||
"items": {
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
"validSince": {
|
||||
"description": "The date (in ISO-8601 format) from which this short code will be valid",
|
||||
"type": "string"
|
||||
},
|
||||
"validUntil": {
|
||||
"description": "The date (in ISO-8601 format) until which this short code will be valid",
|
||||
"type": "string"
|
||||
},
|
||||
"customSlug": {
|
||||
"description": "A unique custom slug to be used instead of the generated short code",
|
||||
"type": "string"
|
||||
},
|
||||
"maxVisits": {
|
||||
"description": "The maximum number of allowed visits for this short code",
|
||||
"type": "number"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"responses": {
|
||||
"200": {
|
||||
"description": "The result of parsing the long URL",
|
||||
"schema": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"longUrl": {
|
||||
"type": "string",
|
||||
"description": "The original long URL that has been parsed"
|
||||
},
|
||||
"shortUrl": {
|
||||
"type": "string",
|
||||
"description": "The generated short URL"
|
||||
},
|
||||
"shortCode": {
|
||||
"type": "string",
|
||||
"description": "the short code that is being used in the short URL"
|
||||
"content": {
|
||||
"application/json": {
|
||||
"schema": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"longUrl": {
|
||||
"type": "string",
|
||||
"description": "The original long URL that has been parsed"
|
||||
},
|
||||
"shortUrl": {
|
||||
"type": "string",
|
||||
"description": "The generated short URL"
|
||||
},
|
||||
"shortCode": {
|
||||
"type": "string",
|
||||
"description": "the short code that is being used in the short URL"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"400": {
|
||||
"description": "The long URL was not provided or is invalid.",
|
||||
"schema": {
|
||||
"$ref": "../definitions/Error.json"
|
||||
"content": {
|
||||
"application/json": {
|
||||
"schema": {
|
||||
"$ref": "../definitions/Error.json"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"500": {
|
||||
"description": "Unexpected error.",
|
||||
"schema": {
|
||||
"$ref": "../definitions/Error.json"
|
||||
"content": {
|
||||
"application/json": {
|
||||
"schema": {
|
||||
"$ref": "../definitions/Error.json"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -9,23 +9,31 @@
|
||||
{
|
||||
"name": "shortCode",
|
||||
"in": "path",
|
||||
"type": "string",
|
||||
"description": "The short code to resolve.",
|
||||
"required": true
|
||||
},
|
||||
"required": true,
|
||||
"schema": {
|
||||
"type": "string"
|
||||
}
|
||||
}
|
||||
],
|
||||
"security": [
|
||||
{
|
||||
"$ref": "../parameters/Authorization.json"
|
||||
"Bearer": []
|
||||
}
|
||||
],
|
||||
"responses": {
|
||||
"200": {
|
||||
"description": "The long URL behind a short code.",
|
||||
"schema": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"longUrl": {
|
||||
"type": "string",
|
||||
"description": "The original long URL behind the short code."
|
||||
"content": {
|
||||
"application/json": {
|
||||
"schema": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"longUrl": {
|
||||
"type": "string",
|
||||
"description": "The original long URL behind the short code."
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
@@ -37,20 +45,32 @@
|
||||
},
|
||||
"400": {
|
||||
"description": "Provided shortCode does not match the character set currently used by the app to generate short codes.",
|
||||
"schema": {
|
||||
"$ref": "../definitions/Error.json"
|
||||
"content": {
|
||||
"application/json": {
|
||||
"schema": {
|
||||
"$ref": "../definitions/Error.json"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"404": {
|
||||
"description": "No URL was found for provided short code.",
|
||||
"schema": {
|
||||
"$ref": "../definitions/Error.json"
|
||||
"content": {
|
||||
"application/json": {
|
||||
"schema": {
|
||||
"$ref": "../definitions/Error.json"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"500": {
|
||||
"description": "Unexpected error.",
|
||||
"schema": {
|
||||
"$ref": "../definitions/Error.json"
|
||||
"content": {
|
||||
"application/json": {
|
||||
"schema": {
|
||||
"$ref": "../definitions/Error.json"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -66,33 +86,41 @@
|
||||
{
|
||||
"name": "shortCode",
|
||||
"in": "path",
|
||||
"type": "string",
|
||||
"description": "The short code to edit.",
|
||||
"required": true
|
||||
},
|
||||
"required": true,
|
||||
"schema": {
|
||||
"type": "string"
|
||||
}
|
||||
}
|
||||
],
|
||||
"requestBody": {
|
||||
"description": "Request body.",
|
||||
"required": true,
|
||||
"content": {
|
||||
"application/json": {
|
||||
"schema": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"validSince": {
|
||||
"description": "The date (in ISO-8601 format) from which this short code will be valid",
|
||||
"type": "string"
|
||||
},
|
||||
"validUntil": {
|
||||
"description": "The date (in ISO-8601 format) until which this short code will be valid",
|
||||
"type": "string"
|
||||
},
|
||||
"maxVisits": {
|
||||
"description": "The maximum number of allowed visits for this short code",
|
||||
"type": "number"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"security": [
|
||||
{
|
||||
"name": "validSince",
|
||||
"in": "formData",
|
||||
"description": "The date (in ISO-8601 format) from which this short code will be valid",
|
||||
"required": false,
|
||||
"type": "string"
|
||||
},
|
||||
{
|
||||
"name": "validUntil",
|
||||
"in": "formData",
|
||||
"description": "The date (in ISO-8601 format) until which this short code will be valid",
|
||||
"required": false,
|
||||
"type": "string"
|
||||
},
|
||||
{
|
||||
"name": "maxVisits",
|
||||
"in": "formData",
|
||||
"description": "The maximum number of allowed visits for this short code",
|
||||
"required": false,
|
||||
"type": "number"
|
||||
},
|
||||
{
|
||||
"$ref": "../parameters/Authorization.json"
|
||||
"Bearer": []
|
||||
}
|
||||
],
|
||||
"responses": {
|
||||
@@ -101,20 +129,32 @@
|
||||
},
|
||||
"400": {
|
||||
"description": "Provided meta arguments are invalid.",
|
||||
"schema": {
|
||||
"$ref": "../definitions/Error.json"
|
||||
"content": {
|
||||
"application/json": {
|
||||
"schema": {
|
||||
"$ref": "../definitions/Error.json"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"404": {
|
||||
"description": "No short URL was found for provided short code.",
|
||||
"schema": {
|
||||
"$ref": "../definitions/Error.json"
|
||||
"content": {
|
||||
"application/json": {
|
||||
"schema": {
|
||||
"$ref": "../definitions/Error.json"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"500": {
|
||||
"description": "Unexpected error.",
|
||||
"schema": {
|
||||
"$ref": "../definitions/Error.json"
|
||||
"content": {
|
||||
"application/json": {
|
||||
"schema": {
|
||||
"$ref": "../definitions/Error.json"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -10,34 +10,55 @@
|
||||
{
|
||||
"name": "shortCode",
|
||||
"in": "path",
|
||||
"type": "string",
|
||||
"description": "The shortCode in which we want to edit tags.",
|
||||
"required": true
|
||||
},
|
||||
{
|
||||
"name": "tags",
|
||||
"in": "formData",
|
||||
"type": "array",
|
||||
"items": {
|
||||
"required": true,
|
||||
"schema": {
|
||||
"type": "string"
|
||||
},
|
||||
"description": "The list of tags to set to the short URL.",
|
||||
"required": true
|
||||
},
|
||||
}
|
||||
}
|
||||
],
|
||||
"requestBody": {
|
||||
"description": "Request body.",
|
||||
"required": true,
|
||||
"content": {
|
||||
"application/json": {
|
||||
"schema": {
|
||||
"type": "object",
|
||||
"required": [
|
||||
"tags"
|
||||
],
|
||||
"properties": {
|
||||
"tags": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"type": "string"
|
||||
},
|
||||
"description": "The list of tags to set to the short URL."
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"security": [
|
||||
{
|
||||
"$ref": "../parameters/Authorization.json"
|
||||
"Bearer": []
|
||||
}
|
||||
],
|
||||
"responses": {
|
||||
"200": {
|
||||
"description": "List of tags.",
|
||||
"schema": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"tags": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"type": "string"
|
||||
"content": {
|
||||
"application/json": {
|
||||
"schema": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"tags": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"type": "string"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -53,20 +74,32 @@
|
||||
},
|
||||
"400": {
|
||||
"description": "The request body does not contain a \"tags\" param with array type.",
|
||||
"schema": {
|
||||
"$ref": "../definitions/Error.json"
|
||||
"content": {
|
||||
"application/json": {
|
||||
"schema": {
|
||||
"$ref": "../definitions/Error.json"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"404": {
|
||||
"description": "No short URL was found for provided short code.",
|
||||
"schema": {
|
||||
"$ref": "../definitions/Error.json"
|
||||
"content": {
|
||||
"application/json": {
|
||||
"schema": {
|
||||
"$ref": "../definitions/Error.json"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"500": {
|
||||
"description": "Unexpected error.",
|
||||
"schema": {
|
||||
"$ref": "../definitions/Error.json"
|
||||
"content": {
|
||||
"application/json": {
|
||||
"schema": {
|
||||
"$ref": "../definitions/Error.json"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -10,27 +10,35 @@
|
||||
{
|
||||
"name": "shortCode",
|
||||
"in": "path",
|
||||
"type": "string",
|
||||
"description": "The shortCode from which we want to get the visits.",
|
||||
"required": true
|
||||
},
|
||||
"required": true,
|
||||
"schema": {
|
||||
"type": "string"
|
||||
}
|
||||
}
|
||||
],
|
||||
"security": [
|
||||
{
|
||||
"$ref": "../parameters/Authorization.json"
|
||||
"Bearer": []
|
||||
}
|
||||
],
|
||||
"responses": {
|
||||
"200": {
|
||||
"description": "List of visits.",
|
||||
"schema": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"visits": {
|
||||
"content": {
|
||||
"application/json": {
|
||||
"schema": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"data": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"$ref": "../definitions/Visit.json"
|
||||
"visits": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"data": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"$ref": "../definitions/Visit.json"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -66,14 +74,22 @@
|
||||
},
|
||||
"404": {
|
||||
"description": "The short code does not belong to any short URL.",
|
||||
"schema": {
|
||||
"$ref": "../definitions/Error.json"
|
||||
"content": {
|
||||
"application/json": {
|
||||
"schema": {
|
||||
"$ref": "../definitions/Error.json"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"500": {
|
||||
"description": "Unexpected error.",
|
||||
"schema": {
|
||||
"$ref": "../definitions/Error.json"
|
||||
"content": {
|
||||
"application/json": {
|
||||
"schema": {
|
||||
"$ref": "../definitions/Error.json"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -5,24 +5,28 @@
|
||||
],
|
||||
"summary": "List existing tags",
|
||||
"description": "Returns the list of all tags used in any short URL, ordered by name",
|
||||
"parameters": [
|
||||
"security": [
|
||||
{
|
||||
"$ref": "../parameters/Authorization.json"
|
||||
"Bearer": []
|
||||
}
|
||||
],
|
||||
"responses": {
|
||||
"200": {
|
||||
"description": "The list of tags",
|
||||
"schema": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"tags": {
|
||||
"content": {
|
||||
"application/json": {
|
||||
"schema": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"data": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"type": "string"
|
||||
"tags": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"data": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"type": "string"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -44,8 +48,12 @@
|
||||
},
|
||||
"500": {
|
||||
"description": "Unexpected error.",
|
||||
"schema": {
|
||||
"$ref": "../definitions/Error.json"
|
||||
"content": {
|
||||
"application/json": {
|
||||
"schema": {
|
||||
"$ref": "../definitions/Error.json"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -57,31 +65,51 @@
|
||||
],
|
||||
"summary": "Create tags",
|
||||
"description": "Provided a list of tags, creates all that do not yet exist",
|
||||
"parameters": [
|
||||
"security": [
|
||||
{
|
||||
"$ref": "../parameters/Authorization.json"
|
||||
},
|
||||
{
|
||||
"name": "tags[]",
|
||||
"in": "formData",
|
||||
"description": "The list of tag names to create",
|
||||
"required": true,
|
||||
"type": "array"
|
||||
"Bearer": []
|
||||
}
|
||||
],
|
||||
"requestBody": {
|
||||
"description": "Request body.",
|
||||
"required": true,
|
||||
"content": {
|
||||
"application/json": {
|
||||
"schema": {
|
||||
"type": "object",
|
||||
"required": [
|
||||
"tags"
|
||||
],
|
||||
"properties": {
|
||||
"tags": {
|
||||
"description": "The list of tag names to create",
|
||||
"type": "array",
|
||||
"items": {
|
||||
"type": "string"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"responses": {
|
||||
"200": {
|
||||
"description": "The list of tags",
|
||||
"schema": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"tags": {
|
||||
"content": {
|
||||
"application/json": {
|
||||
"schema": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"data": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"type": "string"
|
||||
"tags": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"data": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"type": "string"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -103,8 +131,12 @@
|
||||
},
|
||||
"500": {
|
||||
"description": "Unexpected error.",
|
||||
"schema": {
|
||||
"$ref": "../definitions/Error.json"
|
||||
"content": {
|
||||
"application/json": {
|
||||
"schema": {
|
||||
"$ref": "../definitions/Error.json"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -116,45 +148,68 @@
|
||||
],
|
||||
"summary": "Rename tag",
|
||||
"description": "Renames one existing tag",
|
||||
"parameters": [
|
||||
"security": [
|
||||
{
|
||||
"$ref": "../parameters/Authorization.json"
|
||||
},
|
||||
{
|
||||
"name": "oldName",
|
||||
"in": "formData",
|
||||
"description": "Current name of the tag",
|
||||
"required": true,
|
||||
"type": "string"
|
||||
},
|
||||
{
|
||||
"name": "newName",
|
||||
"in": "formData",
|
||||
"description": "New name of the tag",
|
||||
"required": true,
|
||||
"type": "string"
|
||||
"Bearer": []
|
||||
}
|
||||
],
|
||||
"requestBody": {
|
||||
"description": "Request body.",
|
||||
"required": true,
|
||||
"content": {
|
||||
"application/json": {
|
||||
"schema": {
|
||||
"type": "object",
|
||||
"required": [
|
||||
"oldName",
|
||||
"newName"
|
||||
],
|
||||
"properties": {
|
||||
"oldName": {
|
||||
"description": "Current name of the tag",
|
||||
"type": "string"
|
||||
},
|
||||
"newName": {
|
||||
"description": "New name of the tag",
|
||||
"type": "string"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"responses": {
|
||||
"204": {
|
||||
"description": "The tag has been properly renamed"
|
||||
},
|
||||
"400": {
|
||||
"description": "You have not provided either the oldName or the newName params.",
|
||||
"schema": {
|
||||
"$ref": "../definitions/Error.json"
|
||||
"content": {
|
||||
"application/json": {
|
||||
"schema": {
|
||||
"$ref": "../definitions/Error.json"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"404": {
|
||||
"description": "There's no tag found with the name provided in oldName param.",
|
||||
"schema": {
|
||||
"$ref": "../definitions/Error.json"
|
||||
"content": {
|
||||
"application/json": {
|
||||
"schema": {
|
||||
"$ref": "../definitions/Error.json"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"500": {
|
||||
"description": "Unexpected error.",
|
||||
"schema": {
|
||||
"$ref": "../definitions/Error.json"
|
||||
"content": {
|
||||
"application/json": {
|
||||
"schema": {
|
||||
"$ref": "../definitions/Error.json"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -167,15 +222,22 @@
|
||||
"summary": "Delete tags",
|
||||
"description": "Deletes provided list of tags",
|
||||
"parameters": [
|
||||
{
|
||||
"$ref": "../parameters/Authorization.json"
|
||||
},
|
||||
{
|
||||
"name": "tags[]",
|
||||
"in": "query",
|
||||
"description": "The names of the tags to delete",
|
||||
"required": true,
|
||||
"type": "array"
|
||||
"schema": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"type": "string"
|
||||
}
|
||||
}
|
||||
}
|
||||
],
|
||||
"security": [
|
||||
{
|
||||
"Bearer": []
|
||||
}
|
||||
],
|
||||
"responses": {
|
||||
@@ -184,8 +246,12 @@
|
||||
},
|
||||
"500": {
|
||||
"description": "Unexpected error.",
|
||||
"schema": {
|
||||
"$ref": "../definitions/Error.json"
|
||||
"content": {
|
||||
"application/json": {
|
||||
"schema": {
|
||||
"$ref": "../definitions/Error.json"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,23 +1,37 @@
|
||||
{
|
||||
"swagger": "2.0",
|
||||
"openapi": "3.0.0",
|
||||
"info": {
|
||||
"title": "Shlink",
|
||||
"description": "Shlink, the self-hosted URL shortener",
|
||||
"version": "1.0"
|
||||
},
|
||||
"schemes": [
|
||||
"http",
|
||||
"https"
|
||||
],
|
||||
"basePath": "/rest",
|
||||
"produces": [
|
||||
"application/json"
|
||||
],
|
||||
"consumes": [
|
||||
"application/x-www-form-urlencoded",
|
||||
"application/json"
|
||||
|
||||
"servers": [
|
||||
{
|
||||
"url": "{schema}://{server}/rest",
|
||||
"variables": {
|
||||
"schema": {
|
||||
"default": "https",
|
||||
"enum": ["https", "http"]
|
||||
},
|
||||
"server": {
|
||||
"default": ""
|
||||
}
|
||||
}
|
||||
}
|
||||
],
|
||||
|
||||
"components": {
|
||||
"securitySchemes": {
|
||||
"Bearer": {
|
||||
"description": "The JWT identifying a previously logged API key",
|
||||
"type": "http",
|
||||
"scheme": "bearer",
|
||||
"bearerFormat": "JWT"
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
"paths": {
|
||||
"/v1/authenticate": {
|
||||
"$ref": "paths/v1_authenticate.json"
|
||||
|
||||
@@ -6,7 +6,7 @@ namespace Shlinkio\Shlink\Common\Factory;
|
||||
use Interop\Container\ContainerInterface;
|
||||
use Interop\Container\Exception\ContainerException;
|
||||
use Zend\Diactoros\Response\EmptyResponse;
|
||||
use Zend\Expressive\Middleware\ImplicitOptionsMiddleware;
|
||||
use Zend\Expressive\Router\Middleware\ImplicitOptionsMiddleware;
|
||||
use Zend\ServiceManager\Exception\ServiceNotCreatedException;
|
||||
use Zend\ServiceManager\Exception\ServiceNotFoundException;
|
||||
use Zend\ServiceManager\Factory\FactoryInterface;
|
||||
|
||||
@@ -6,7 +6,7 @@ namespace ShlinkioTest\Shlink\Common\Factory;
|
||||
use PHPUnit\Framework\TestCase;
|
||||
use Shlinkio\Shlink\Common\Factory\EmptyResponseImplicitOptionsMiddlewareFactory;
|
||||
use Zend\Diactoros\Response\EmptyResponse;
|
||||
use Zend\Expressive\Middleware\ImplicitOptionsMiddleware;
|
||||
use Zend\Expressive\Router\Middleware\ImplicitOptionsMiddleware;
|
||||
use Zend\ServiceManager\ServiceManager;
|
||||
|
||||
class EmptyResponseImplicitOptionsMiddlewareFactoryTest extends TestCase
|
||||
|
||||
@@ -17,6 +17,8 @@ use Zend\Expressive\Router\Route;
|
||||
use Zend\Expressive\Router\RouteResult;
|
||||
use Zend\I18n\Translator\Translator;
|
||||
|
||||
use function Zend\Stratigility\middleware;
|
||||
|
||||
class CheckAuthenticationMiddlewareTest extends TestCase
|
||||
{
|
||||
/**
|
||||
@@ -28,10 +30,18 @@ class CheckAuthenticationMiddlewareTest extends TestCase
|
||||
*/
|
||||
protected $jwtService;
|
||||
|
||||
/**
|
||||
* @var callable
|
||||
*/
|
||||
protected $dummyMiddleware;
|
||||
|
||||
public function setUp()
|
||||
{
|
||||
$this->jwtService = $this->prophesize(JWTService::class);
|
||||
$this->middleware = new CheckAuthenticationMiddleware($this->jwtService->reveal(), Translator::factory([]));
|
||||
$this->dummyMiddleware = middleware(function ($request, $handler) {
|
||||
return new Response\EmptyResponse;
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -59,7 +69,12 @@ class CheckAuthenticationMiddlewareTest extends TestCase
|
||||
|
||||
$request = ServerRequestFactory::fromGlobals()->withAttribute(
|
||||
RouteResult::class,
|
||||
RouteResult::fromRoute(new Route('foo', '', Route::HTTP_METHOD_ANY, AuthenticateAction::class))
|
||||
RouteResult::fromRoute(new Route(
|
||||
'foo',
|
||||
$this->dummyMiddleware,
|
||||
Route::HTTP_METHOD_ANY,
|
||||
AuthenticateAction::class
|
||||
))
|
||||
);
|
||||
$delegate = $this->prophesize(DelegateInterface::class);
|
||||
/** @var MethodProphecy $process */
|
||||
@@ -69,7 +84,7 @@ class CheckAuthenticationMiddlewareTest extends TestCase
|
||||
|
||||
$request = ServerRequestFactory::fromGlobals()->withAttribute(
|
||||
RouteResult::class,
|
||||
RouteResult::fromRoute(new Route('bar', 'foo'), [])
|
||||
RouteResult::fromRoute(new Route('bar', $this->dummyMiddleware), [])
|
||||
)->withMethod('OPTIONS');
|
||||
$delegate = $this->prophesize(DelegateInterface::class);
|
||||
/** @var MethodProphecy $process */
|
||||
@@ -85,7 +100,7 @@ class CheckAuthenticationMiddlewareTest extends TestCase
|
||||
{
|
||||
$request = ServerRequestFactory::fromGlobals()->withAttribute(
|
||||
RouteResult::class,
|
||||
RouteResult::fromRoute(new Route('bar', 'foo'), [])
|
||||
RouteResult::fromRoute(new Route('bar', $this->dummyMiddleware), [])
|
||||
);
|
||||
$response = $this->middleware->process($request, TestUtils::createDelegateMock()->reveal());
|
||||
$this->assertEquals(401, $response->getStatusCode());
|
||||
@@ -99,7 +114,7 @@ class CheckAuthenticationMiddlewareTest extends TestCase
|
||||
$authToken = 'ABC-abc';
|
||||
$request = ServerRequestFactory::fromGlobals()->withAttribute(
|
||||
RouteResult::class,
|
||||
RouteResult::fromRoute(new Route('bar', 'foo'), [])
|
||||
RouteResult::fromRoute(new Route('bar', $this->dummyMiddleware), [])
|
||||
)->withHeader(CheckAuthenticationMiddleware::AUTHORIZATION_HEADER, $authToken);
|
||||
|
||||
$response = $this->middleware->process($request, TestUtils::createDelegateMock()->reveal());
|
||||
@@ -116,7 +131,7 @@ class CheckAuthenticationMiddlewareTest extends TestCase
|
||||
$authToken = 'ABC-abc';
|
||||
$request = ServerRequestFactory::fromGlobals()->withAttribute(
|
||||
RouteResult::class,
|
||||
RouteResult::fromRoute(new Route('bar', 'foo'), [])
|
||||
RouteResult::fromRoute(new Route('bar', $this->dummyMiddleware), [])
|
||||
)->withHeader(CheckAuthenticationMiddleware::AUTHORIZATION_HEADER, 'Basic ' . $authToken);
|
||||
|
||||
$response = $this->middleware->process($request, TestUtils::createDelegateMock()->reveal());
|
||||
@@ -135,7 +150,7 @@ class CheckAuthenticationMiddlewareTest extends TestCase
|
||||
$authToken = 'ABC-abc';
|
||||
$request = ServerRequestFactory::fromGlobals()->withAttribute(
|
||||
RouteResult::class,
|
||||
RouteResult::fromRoute(new Route('bar', 'foo'), [])
|
||||
RouteResult::fromRoute(new Route('bar', $this->dummyMiddleware), [])
|
||||
)->withHeader(CheckAuthenticationMiddleware::AUTHORIZATION_HEADER, 'Bearer ' . $authToken);
|
||||
$this->jwtService->verify($authToken)->willReturn(false)->shouldBeCalledTimes(1);
|
||||
|
||||
@@ -151,7 +166,7 @@ class CheckAuthenticationMiddlewareTest extends TestCase
|
||||
$authToken = 'ABC-abc';
|
||||
$request = ServerRequestFactory::fromGlobals()->withAttribute(
|
||||
RouteResult::class,
|
||||
RouteResult::fromRoute(new Route('bar', 'foo'), [])
|
||||
RouteResult::fromRoute(new Route('bar', $this->dummyMiddleware), [])
|
||||
)->withHeader(CheckAuthenticationMiddleware::AUTHORIZATION_HEADER, 'bearer ' . $authToken);
|
||||
$this->jwtService->verify($authToken)->willReturn(true)->shouldBeCalledTimes(1);
|
||||
$this->jwtService->refresh($authToken)->willReturn($authToken)->shouldBeCalledTimes(1);
|
||||
|
||||
Reference in New Issue
Block a user