Skip to content

Commit a367d20

Browse files
authored
Merge pull request #575 from leepeuker/add-auth-api
Add API endpoint for retreiving an auth token
2 parents d60534e + dbed0b4 commit a367d20

23 files changed

+580
-240
lines changed
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
<?php declare(strict_types=1);
2+
3+
use Phinx\Migration\AbstractMigration;
4+
5+
final class AddDeviceNameAndUserAgentToAuthTokenTable extends AbstractMigration
6+
{
7+
public function down() : void
8+
{
9+
$this->execute(
10+
<<<SQL
11+
ALTER TABLE `user_auth_token` DROP COLUMN device_name;
12+
ALTER TABLE `user_auth_token` DROP COLUMN user_agent;
13+
SQL,
14+
);
15+
}
16+
17+
public function up() : void
18+
{
19+
$this->execute(
20+
<<<SQL
21+
DELETE FROM `user_auth_token`;
22+
ALTER TABLE `user_auth_token` ADD COLUMN device_name VARCHAR(256) NOT NULL;
23+
ALTER TABLE `user_auth_token` ADD COLUMN user_agent TEXT NOT NULL;
24+
SQL,
25+
);
26+
}
27+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
<?php declare(strict_types=1);
2+
3+
use Phinx\Migration\AbstractMigration;
4+
5+
final class AddDeviceNameAndUserAgentToAuthTokenTable extends AbstractMigration
6+
{
7+
public function down() : void
8+
{
9+
$this->execute(
10+
<<<SQL
11+
CREATE TABLE `user_auth_token_tmp` (
12+
`id` INTEGER NOT NULL,
13+
`user_id` INTEGER NOT NULL,
14+
`token` TEXT NOT NULL,
15+
`expiration_date` TEXT NOT NULL,
16+
`created_at` TEXT NOT NULL,
17+
PRIMARY KEY (`id`),
18+
FOREIGN KEY (`user_id`) REFERENCES user (`id`) ON DELETE CASCADE
19+
)
20+
SQL,
21+
);
22+
$this->execute('INSERT INTO `user_auth_token_tmp` (`id`, `user_id`, `token`, `expiration_date`, `created_at`) SELECT `id`, `user_id`, `token`, `expiration_date`, `created_at` FROM `user_auth_token`');
23+
$this->execute('DROP TABLE `user_auth_token`');
24+
$this->execute('ALTER TABLE `user_auth_token_tmp` RENAME TO `user_auth_token`');
25+
}
26+
27+
public function up() : void
28+
{
29+
$this->execute(
30+
<<<SQL
31+
CREATE TABLE `user_auth_token_tmp` (
32+
`id` INTEGER NOT NULL,
33+
`user_id` INT(10) NOT NULL,
34+
`token` CHAR(36) NOT NULL,
35+
`device_name` VARCHAR(256) NOT NULL,
36+
`user_agent` TEXT NOT NULL,
37+
`expiration_date` TEXT NOT NULL,
38+
`created_at` TEXT NOT NULL,
39+
PRIMARY KEY (`id`),
40+
FOREIGN KEY (`user_id`) REFERENCES user (`id`) ON DELETE CASCADE
41+
)
42+
SQL,
43+
);
44+
$this->execute('DROP TABLE `user_auth_token`');
45+
$this->execute('ALTER TABLE `user_auth_token_tmp` RENAME TO `user_auth_token`');
46+
}
47+
}

Diff for: docs/openapi.json

+149-13
Original file line numberDiff line numberDiff line change
@@ -111,7 +111,7 @@
111111
},
112112
"security": [
113113
{
114-
"authToken": []
114+
"token": []
115115
}
116116
]
117117
},
@@ -174,7 +174,7 @@
174174
},
175175
"security": [
176176
{
177-
"authToken": []
177+
"token": []
178178
}
179179
]
180180
},
@@ -237,7 +237,7 @@
237237
},
238238
"security": [
239239
{
240-
"authToken": []
240+
"token": []
241241
}
242242
]
243243
},
@@ -291,7 +291,7 @@
291291
},
292292
"security": [
293293
{
294-
"authToken": []
294+
"token": []
295295
}
296296
]
297297
}
@@ -427,7 +427,7 @@
427427
},
428428
"security": [
429429
{
430-
"authToken": []
430+
"token": []
431431
}
432432
]
433433
},
@@ -477,7 +477,7 @@
477477
},
478478
"security": [
479479
{
480-
"authToken": []
480+
"token": []
481481
}
482482
]
483483
},
@@ -527,7 +527,7 @@
527527
},
528528
"security": [
529529
{
530-
"authToken": []
530+
"token": []
531531
}
532532
]
533533
}
@@ -677,7 +677,7 @@
677677
},
678678
"security": [
679679
{
680-
"authToken": []
680+
"token": []
681681
}
682682
]
683683
},
@@ -745,7 +745,7 @@
745745
},
746746
"security": [
747747
{
748-
"authToken": []
748+
"token": []
749749
}
750750
]
751751
},
@@ -813,7 +813,7 @@
813813
},
814814
"security": [
815815
{
816-
"authToken": []
816+
"token": []
817817
}
818818
]
819819
},
@@ -871,7 +871,7 @@
871871
},
872872
"security": [
873873
{
874-
"authToken": []
874+
"token": []
875875
}
876876
]
877877
}
@@ -980,7 +980,7 @@
980980
},
981981
"security": [
982982
{
983-
"authToken": []
983+
"token": []
984984
}
985985
]
986986
}
@@ -1065,6 +1065,93 @@
10651065
}
10661066
}
10671067
}
1068+
},
1069+
"/authentication/token": {
1070+
"post": {
1071+
"tags": [
1072+
"Authentication"
1073+
],
1074+
"description": "Create an authentication token via email, password and optionally TOTP code. Add the token as X-Auth-Token header to further requests. Token lifetime 1d default, 30d with rememberMe.",
1075+
"parameters": [
1076+
{
1077+
"in": "header",
1078+
"name": "X-Movary-Client",
1079+
"schema": {
1080+
"type": "string"
1081+
},
1082+
"required": true,
1083+
"example": "Client Name"
1084+
}
1085+
],
1086+
"requestBody": {
1087+
"description": "The credentials and optionally a two-factor authentication code",
1088+
"required": true,
1089+
"content": {
1090+
"application/json": {
1091+
"schema": {
1092+
"type": "object",
1093+
"required": [
1094+
"email",
1095+
"password"
1096+
],
1097+
"properties": {
1098+
"email": {
1099+
"type": "string",
1100+
"example": "[email protected]",
1101+
"description": "An email address"
1102+
},
1103+
"password": {
1104+
"type": "string",
1105+
"example": "mysecurepassword123",
1106+
"description": "A password"
1107+
},
1108+
"totpCode": {
1109+
"type": "integer",
1110+
"pattern": "/^[0-9]{6}$/gm",
1111+
"example": "123456",
1112+
"description": "A 6-digit two-factor TOTP code",
1113+
"nullable": true
1114+
},
1115+
"rememberMe": {
1116+
"type": "boolean",
1117+
"example": true,
1118+
"description": "Extend auth token lifetime",
1119+
"nullable": true
1120+
}
1121+
}
1122+
}
1123+
}
1124+
}
1125+
},
1126+
"responses": {
1127+
"200": {
1128+
"description": "Returned if authentication was successfully",
1129+
"content": {
1130+
"application/json": {
1131+
"schema": {
1132+
"type": "object",
1133+
"properties": {
1134+
"userId": {
1135+
"type": "integer",
1136+
"description": "The id of the authenticated user."
1137+
},
1138+
"token": {
1139+
"type": "string",
1140+
"description": "The authentication token to be used in future requests."
1141+
}
1142+
}
1143+
}
1144+
}
1145+
}
1146+
},
1147+
"400": {
1148+
"$ref": "#/components/responses/400"
1149+
},
1150+
"401": {
1151+
"$ref": "#/components/responses/401"
1152+
}
1153+
}
1154+
}
10681155
}
10691156
},
10701157
"components": {
@@ -1231,6 +1318,50 @@
12311318
"204": {
12321319
"description": "Successful operation, response has no content"
12331320
},
1321+
"400": {
1322+
"description": "The request payload or header are not correct",
1323+
"content": {
1324+
"application/json": {
1325+
"schema": {
1326+
"type": "object",
1327+
"properties": {
1328+
"error": {
1329+
"type": "string",
1330+
"description": "The error type",
1331+
"example": "ErrorType"
1332+
},
1333+
"message": {
1334+
"type": "string",
1335+
"description": "The error message",
1336+
"example": "This is the error message"
1337+
}
1338+
}
1339+
}
1340+
}
1341+
}
1342+
},
1343+
"401": {
1344+
"description": "The provided credentials or TOTP code are not valid",
1345+
"content": {
1346+
"application/json": {
1347+
"schema": {
1348+
"type": "object",
1349+
"properties": {
1350+
"error": {
1351+
"type": "string",
1352+
"description": "The error type",
1353+
"example": "ErrorType"
1354+
},
1355+
"message": {
1356+
"type": "string",
1357+
"description": "The error message",
1358+
"example": "This is the error message"
1359+
}
1360+
}
1361+
}
1362+
}
1363+
}
1364+
},
12341365
"403": {
12351366
"description": "Not authorized to access resource"
12361367
},
@@ -1239,10 +1370,15 @@
12391370
}
12401371
},
12411372
"securitySchemes": {
1242-
"authToken": {
1373+
"token": {
12431374
"type": "apiKey",
12441375
"name": "X-Auth-Token",
12451376
"in": "header"
1377+
},
1378+
"cookie": {
1379+
"type": "apiKey",
1380+
"name": "id",
1381+
"in": "cookie"
12461382
}
12471383
}
12481384
}

0 commit comments

Comments
 (0)