Missing fields in database

Created on 25 June 2023, over 1 year ago
Updated 8 May 2024, 6 months ago

Hello everyone,

I came across this problem today after installing this module. Would appreciate an answer.

Problem/Motivation

When freshly installing version 2.0.0 for the first time instead of updating from a previous version, the newly added fields created_at and refreshed_at (as in this commit) are not created, leading to the following error (token and secret shortened):

Drupal\Core\Database\DatabaseExceptionWrapper: SQLSTATE[42S22]: Column not found: 1054 Unknown column 'created_at' in 'field list': INSERT INTO "rest_api_access_token" ("user_id", "public_token", "secret", "created_at", "refreshed_at") VALUES (:db_insert_placeholder_0, :db_insert_placeholder_1, :db_insert_placeholder_2, :db_insert_placeholder_3, :db_insert_placeholder_4); Array ( [:db_insert_placeholder_0] => 1 [:db_insert_placeholder_1] => b0b ... 63a [:db_insert_placeholder_2] => b55 ... a50 [:db_insert_placeholder_3] => 1687649665 [:db_insert_placeholder_4] => 1687649665 ) in Drupal\rest_api_access_token\Repository\TokenRepository->insert() (line 87 of modules/contrib/rest_api_access_token/src/Repository/TokenRepository.php).

Steps to reproduce

  1. Install the module on a Drupal installation that never used the module before
  2. Create a new token by calling the endpoint and send login and password as payload
  3. Review HTTP/500 message

Proposed resolution

include database table creation in the install file

Additional newbie question

Is it correct that there is no way to obtain a new token for a logged in user via a GUI (e.g., through the user page)?

🐛 Bug report
Status

Fixed

Version

2.0

Component

Code

Created by

🇩🇪Germany kaelteschutzgebiet

Live updates comments and jobs are added and updated live.
Sign in to follow issues

Comments & Activities

  • Issue created by @kaelteschutzgebiet
  • 🇺🇸United States codesquatch

    I just ran across the issue as well so I created a patch for it.

    To answer your additional question @kaelteschutzgebiet, you'd need to add it into the User Profile page yourself via an alter hook or preprocess hook in your theme. This is how we've done it:

    /**
     * Implements hook_ENTITY_TYPE_view_alter() for user entities.
     *
     * This function adds the user's API Token to their profile form.
     */
    function modulename_user_view_alter(array &$build, UserInterface $account, EntityViewDisplayInterface $display): void {
      // Display API Token for current user.
      if ($account->id() === \Drupal::currentUser()->id()) {
        $token = \Drupal::database()
          ->select(Token::TABLE_NAME, 't')
          ->fields('t', ['public_token'])
          ->condition('user_id', $account->id())
          ->execute()
          ->fetch();
    
        $build['api_token'] = [
          '#type' => 'item',
          '#title' => t('API Session Token'),
          '#label_attributes' => ['class' => ['label']],
          '#plain_text' => $token?->public_token ?? '',
        ];
      }
    }
    
  • 🇮🇳India mukhtarm

    @codesquatch I wonder why the hook_update is used in place for to add these fields? drush updb created the fields for me.

  • 🇺🇸United States codesquatch

    @MukhtarM It could have been an oversight on the implementing developer, or perhaps an assumption that the update would always file since the module would only be supported on D8/9? Either way, installing the module on fresh D9 and D10 (with patch) site throws the error for me that is in the description of the bug. It was causing a headache in situations where the module is a dependency for a distribution.

  • 🇮🇹Italy trickfun

    Drush updb doesn't update the table.
    I have to reinstall module.

  • 🇦🇷Argentina cesarmiquel

    I looked at the .install for this module and the problem is that the fields are added in rest_api_access_token_update_8021() but they should also be added to the rest_api_access_token_schema() function. The way Drupal works is if you install the module for the first time Drupal saves the ID of the last update (8021) and only applies updates that are larger than 8021 but will not run any of the previous updates. For fresh installs you need to put the current version of the table in hook_schema(). Currently I don't have time to create a patch but that is the correct way to fix this AFAIK.
    The rest_api_access_token_schema() should be something like this:

      $schema['rest_api_access_token'] = [
        'description' => 'Stores access tokens.',
        'fields' => [
          'user_id' => [
            'type' => 'int',
            'unsigned' => TRUE,
            'not null' => TRUE,
          ],
          'public_token' => [
            'type' => 'varchar',
            'length' => 128,
            'not null' => TRUE,
          ],
          'secret' => [
            'type' => 'varchar',
            'length' => 128,
            'not null' => TRUE,
          ],
          'created_at' => [
            'description' => 'Created time.',
            'type' => 'int',
            'unsigned' => TRUE,
            'not null' => TRUE,
            'default' => 0,
          ],
          'refreshed_at' => [
            'description' => 'Updated time.',
            'type' => 'int',
           'unsigned' => TRUE,
            'not null' => TRUE,
            'default' => 0,
          ],
        ],
        'indexes' => [
          'public_token' => ['public_token'],
          'user_id' => ['user_id'],
        ],
        'primary key' => ['public_token'],
      ];
    
      return $schema
     

    Also I'm pretty sure that the 'default' => time() doesn't work as the author of the module expected. You can't set a dynamic default value. You should use 0 and make sure to add the timestamp via code.

  • Status changed to Fixed 7 months ago
  • Automatically closed - issue fixed for 2 weeks with no activity.

Production build 0.71.5 2024