1
0
mirror of https://github.com/BookStackApp/BookStack.git synced 2024-11-23 11:22:33 +01:00

Removed token 'client' text, avoid confusion w/ oAuth

- Instead have a token_id and a secret.
   - Displayed a 'Token ID' and 'Token Secret'.
This commit is contained in:
Dan Brown 2019-12-29 20:07:28 +00:00
parent 832fbd65af
commit 692fc46c7d
No known key found for this signature in database
GPG Key ID: 46D9F943C24A2EF9
6 changed files with 24 additions and 24 deletions

View File

@ -44,14 +44,14 @@ class UserApiTokenController extends Controller
$token = (new ApiToken())->forceFill([ $token = (new ApiToken())->forceFill([
'name' => $request->get('name'), 'name' => $request->get('name'),
'client_id' => Str::random(32), 'token_id' => Str::random(32),
'client_secret' => Hash::make($secret), 'secret' => Hash::make($secret),
'user_id' => $user->id, 'user_id' => $user->id,
'expires_at' => $expiry 'expires_at' => $expiry
]); ]);
while (ApiToken::query()->where('client_id', '=', $token->client_id)->exists()) { while (ApiToken::query()->where('token_id', '=', $token->token_id)->exists()) {
$token->client_id = Str::random(32); $token->token_id = Str::random(32);
} }
$token->save(); $token->save();

View File

@ -19,8 +19,8 @@ class AddApiAuth extends Migration
Schema::create('api_tokens', function(Blueprint $table) { Schema::create('api_tokens', function(Blueprint $table) {
$table->increments('id'); $table->increments('id');
$table->string('name'); $table->string('name');
$table->string('client_id')->unique(); $table->string('token_id')->unique();
$table->string('client_secret'); $table->string('secret');
$table->integer('user_id')->unsigned()->index(); $table->integer('user_id')->unsigned()->index();
$table->date('expires_at')->index(); $table->date('expires_at')->index();
$table->nullableTimestamps(); $table->nullableTimestamps();

View File

@ -163,14 +163,14 @@ return [
'user_api_token_name_desc' => 'Give your token a readable name as a future reminder of its intended purpose.', 'user_api_token_name_desc' => 'Give your token a readable name as a future reminder of its intended purpose.',
'user_api_token_expiry' => 'Expiry Date', 'user_api_token_expiry' => 'Expiry Date',
'user_api_token_expiry_desc' => 'Set a date at which this token expires. After this date, requests made using this token will no longer work. Leaving this field blank will set an expiry 100 years into the future.', 'user_api_token_expiry_desc' => 'Set a date at which this token expires. After this date, requests made using this token will no longer work. Leaving this field blank will set an expiry 100 years into the future.',
'user_api_token_create_secret_message' => 'Immediately after creating this token a "client id"" & "client secret" will be generated and displayed. The client secret will only be shown a single time so be sure to copy the value to somewhere safe and secure before proceeding.', 'user_api_token_create_secret_message' => 'Immediately after creating this token a "Token ID"" & "Token Secret" will be generated and displayed. The secret will only be shown a single time so be sure to copy the value to somewhere safe and secure before proceeding.',
'user_api_token_create_success' => 'API token successfully created', 'user_api_token_create_success' => 'API token successfully created',
'user_api_token_update_success' => 'API token successfully updated', 'user_api_token_update_success' => 'API token successfully updated',
'user_api_token' => 'API Token', 'user_api_token' => 'API Token',
'user_api_token_client_id' => 'Client ID', 'user_api_token_id' => 'Token ID',
'user_api_token_client_id_desc' => 'This is a non-editable system generated identifier for this token which will need to be provided in API requests.', 'user_api_token_id_desc' => 'This is a non-editable system generated identifier for this token which will need to be provided in API requests.',
'user_api_token_client_secret' => 'Client Secret', 'user_api_token_secret' => 'Token Secret',
'user_api_token_client_secret_desc' => 'This is a system generated secret for this token which will need to be provided in API requests. This will only be displayed this one time so copy this value to somewhere safe and secure.', 'user_api_token_secret_desc' => 'This is a system generated secret for this token which will need to be provided in API requests. This will only be displayed this one time so copy this value to somewhere safe and secure.',
'user_api_token_created' => 'Token Created :timeAgo', 'user_api_token_created' => 'Token Created :timeAgo',
'user_api_token_updated' => 'Token Updated :timeAgo', 'user_api_token_updated' => 'Token Updated :timeAgo',
'user_api_token_delete' => 'Delete Token', 'user_api_token_delete' => 'Delete Token',

View File

@ -15,11 +15,11 @@
<div class="grid half gap-xl v-center"> <div class="grid half gap-xl v-center">
<div> <div>
<label class="setting-list-label">{{ trans('settings.user_api_token_client_id') }}</label> <label class="setting-list-label">{{ trans('settings.user_api_token_id') }}</label>
<p class="small">{{ trans('settings.user_api_token_client_id_desc') }}</p> <p class="small">{{ trans('settings.user_api_token_id_desc') }}</p>
</div> </div>
<div> <div>
@include('form.text', ['name' => 'client_id', 'readonly' => true]) @include('form.text', ['name' => 'token_id', 'readonly' => true])
</div> </div>
</div> </div>
@ -27,8 +27,8 @@
@if( $secret ) @if( $secret )
<div class="grid half gap-xl v-center"> <div class="grid half gap-xl v-center">
<div> <div>
<label class="setting-list-label">{{ trans('settings.user_api_token_client_secret') }}</label> <label class="setting-list-label">{{ trans('settings.user_api_token_secret') }}</label>
<p class="small text-warn">{{ trans('settings.user_api_token_client_secret_desc') }}</p> <p class="small text-warn">{{ trans('settings.user_api_token_secret_desc') }}</p>
</div> </div>
<div> <div>
<input type="text" readonly="readonly" value="{{ $secret }}"> <input type="text" readonly="readonly" value="{{ $secret }}">

View File

@ -109,7 +109,7 @@
<tr> <tr>
<td> <td>
{{ $token->name }} <br> {{ $token->name }} <br>
<span class="small text-muted italic">{{ $token->client_id }}</span> <span class="small text-muted italic">{{ $token->token_id }}</span>
</td> </td>
<td>{{ $token->expires_at->format('Y-m-d') ?? '' }}</td> <td>{{ $token->expires_at->format('Y-m-d') ?? '' }}</td>
<td class="text-right"> <td class="text-right">

View File

@ -44,7 +44,7 @@ class UserApiTokenTest extends TestCase
$resp = $this->asAdmin()->get($editor->getEditUrl('/create-api-token')); $resp = $this->asAdmin()->get($editor->getEditUrl('/create-api-token'));
$resp->assertStatus(200); $resp->assertStatus(200);
$resp->assertSee('Create API Token'); $resp->assertSee('Create API Token');
$resp->assertSee('client secret'); $resp->assertSee('Token Secret');
$resp = $this->post($editor->getEditUrl('/create-api-token'), $this->testTokenData); $resp = $this->post($editor->getEditUrl('/create-api-token'), $this->testTokenData);
$token = ApiToken::query()->latest()->first(); $token = ApiToken::query()->latest()->first();
@ -59,11 +59,11 @@ class UserApiTokenTest extends TestCase
$this->assertSessionHas('api-token-secret:' . $token->id); $this->assertSessionHas('api-token-secret:' . $token->id);
$secret = session('api-token-secret:' . $token->id); $secret = session('api-token-secret:' . $token->id);
$this->assertDatabaseMissing('api_tokens', [ $this->assertDatabaseMissing('api_tokens', [
'client_secret' => $secret, 'secret' => $secret,
]); ]);
$this->assertTrue(\Hash::check($secret, $token->client_secret)); $this->assertTrue(\Hash::check($secret, $token->secret));
$this->assertTrue(strlen($token->client_id) === 32); $this->assertTrue(strlen($token->token_id) === 32);
$this->assertTrue(strlen($secret) === 32); $this->assertTrue(strlen($secret) === 32);
$this->assertSessionHas('success'); $this->assertSessionHas('success');
@ -92,15 +92,15 @@ class UserApiTokenTest extends TestCase
$resp = $this->get($editor->getEditUrl()); $resp = $this->get($editor->getEditUrl());
$resp->assertElementExists('#api_tokens'); $resp->assertElementExists('#api_tokens');
$resp->assertElementContains('#api_tokens', $token->name); $resp->assertElementContains('#api_tokens', $token->name);
$resp->assertElementContains('#api_tokens', $token->client_id); $resp->assertElementContains('#api_tokens', $token->token_id);
$resp->assertElementContains('#api_tokens', $token->expires_at->format('Y-m-d')); $resp->assertElementContains('#api_tokens', $token->expires_at->format('Y-m-d'));
} }
public function test_client_secret_shown_once_after_creation() public function test_secret_shown_once_after_creation()
{ {
$editor = $this->getEditor(); $editor = $this->getEditor();
$resp = $this->asAdmin()->followingRedirects()->post($editor->getEditUrl('/create-api-token'), $this->testTokenData); $resp = $this->asAdmin()->followingRedirects()->post($editor->getEditUrl('/create-api-token'), $this->testTokenData);
$resp->assertSeeText('Client Secret'); $resp->assertSeeText('Token Secret');
$token = ApiToken::query()->latest()->first(); $token = ApiToken::query()->latest()->first();
$this->assertNull(session('api-token-secret:' . $token->id)); $this->assertNull(session('api-token-secret:' . $token->id));