1

I'm trying to begin programming an api for an android application and wanted to use node.js + loopback for this. But I'm running into some trouble testing/ learning the language.

Following code should generate new users in my database(and it does) but when I try to login with this user no AccessToken in created an printen to the console. Any idea what I'm doing wrong?

My Test code: create-test-data.js

var app = require('./app');
var dataSource = app.dataSources.mysql;
var loopback = require('loopback');
var User = loopback.User; // Getting User Model
var AccessToken = loopback.AccessToken; // Getting AccessTokenModel

/*
Initializing the database done by this. If already exist it will clean it.
dataSource.automigrate('user', function (err) {});
dataSource.automigrate('account', function (err) {});
dataSource.automigrate('accesstoken', function (err) {});
*/

//Creating some users in mysql database
User.create({username: 'timbo', email: 'test@gmail.com', password: 'monkey123'} , function(err, user) {console.log(user);});

User.create({username: 'timbo2', email: 'test2@gmail.com', password: 'monkey123'} , function(err,user) {console.log(user);});

User.create({username: 'timbo3', email: 'test3@gmail.com', password: 'monkey123'} , function(err,user) {console.log(user);});

User.login({username: 'timbo', password: 'monkey123'}, function(err, accesstoken) {console.log("This is the token: " + accesstoken);});
//No accesstoken created / saved in the database

datasource.json

{
  "db": {
    "defaultForType": "db",
    "connector": "mysql",
    "host": "127.0.0.1",
    "database": "test",
    "user": "root",
    "password": "warcraft"
  },
  "push": {
    "defaultForType": "push",
    "connector": "loopback-push-notification",
    "installation": "installation",
    "notification": "notification",
    "application": "application"
  },
  "mail": {
    "defaultForType": "mail",
    "connector": "mail"
  },
  "mysql": {
    "connector": "mysql",
    "host": "127.0.0.1",
    "database": "test",
    "user": "root",
    "password": "warcraft"
  }
}

models.json

{
  "email": {
    "options": {
      "base": "Email"
    },
    "dataSource": "mail",
    "public": false
  },
  "user": {
    "options": {
      "base": "User",
      "relations": {
        "accessTokens": {
          "model": "accessToken",
          "type": "hasMany",
          "foreignKey": "userId"
        }
      }
    },
    "dataSource": "mysql",
    "public": true
  },
  "accessToken": {
    "options": {
      "base": "AccessToken"
    },
    "dataSource": "mysql",
    "public": true
  },
  "application": {
    "options": {
      "base": "Application"
    },
    "dataSource": "db",
    "public": true
  },
  "acl": {
    "options": {
      "base": "ACL"
    },
    "dataSource": "db",
    "public": false
  },
  "roleMapping": {
    "options": {
      "base": "RoleMapping"
    },
    "dataSource": "db",
    "public": false
  },
  "role": {
    "options": {
      "base": "Role",
      "relations": {
        "principals": {
          "type": "hasMany",
          "model": "roleMapping",
          "foreignKey": "roleId"
        }
      }
    },
    "dataSource": "db",
    "public": false
  },
  "scope": {
    "options": {
      "base": "Scope"
    },
    "dataSource": "db",
    "public": false
  },
  "push": {
    "options": {
      "base": "Push",
      "plural": "push"
    },
    "dataSource": "push"
  },
  "installation": {
    "options": {
      "base": "Installation"
    },
    "dataSource": "db",
    "public": true
  },
  "notification": {
    "options": {
      "base": "Notification"
    },
    "dataSource": "db",
    "public": true
  },
  "product": {
    "properties": {
      "email": {
        "type": "string"
      },
      "level": {
        "type": "number"
      },
      "create": {
        "type": "date"
      },
      "modified": {
        "type": "date"
      }
    },
    "public": true,
    "dataSource": "db",
    "plural": "products"
  },
  "account": {
    "properties": {
      "email": {
        "type": "string"
      },
      "level": {
        "type": "number"
      },
      "created": {
        "type": "date"
      },
      "modified": {
        "type": "date"
      }
    },
    "public": true,
    "dataSource": "mysql",
    "plural": "accounts"
  }
}

Console Output

{ username: 'timbo',
  email: 'test@gmail.com',
  password: '$2a$10$972DFwMOuOhKj5ThfbchC.ipcNaW27ccpHMRkW17uSLutaCHyZF0G',
  realm: undefined,
  emailVerified: undefined,
  verificationToken: undefined,
  credentials: [],
  challenges: [],
  status: undefined,
  created: undefined,
  lastUpdated: undefined,
  id: undefined }
{ username: 'timbo2',
  email: 'test2@gmail.com',
  password: '$2a$10$1peSixaOIQq8umOzzEy86OQKxoPFU.Ax2/NWC1oLGjQHPp9oZdPDW',
  realm: undefined,
  emailVerified: undefined,
  verificationToken: undefined,
  credentials: [],
  challenges: [],
  status: undefined,
  created: undefined,
  lastUpdated: undefined,
  id: undefined }
{ username: 'timbo3',
  email: 'test3@gmail.com',
  password: '$2a$10$X3fdV2dL6kjuj69Dqr.jMeVdqIMzveN7NnJP5TXag54b4tpzZ4LGW',
  realm: undefined,
  emailVerified: undefined,
  verificationToken: undefined,
  credentials: [],
  challenges: [],
  status: undefined,
  created: undefined,
  lastUpdated: undefined,
  id: undefined }
This is the token: undefined
This is the token err: Error: ER_BAD_FIELD_ERROR: Unknown column 'ttl' in 'field list'
Craig Ringer
  • 307,061
  • 76
  • 688
  • 778
Timbo925
  • 281
  • 4
  • 16
  • What is the value of `err` in the token callback? – Itay Grudev Mar 10 '14 at 11:59
  • This is the token err: Error: ER_BAD_FIELD_ERROR: Unknown column 'ttl' in 'field list' – Timbo925 Mar 10 '14 at 12:12
  • My err object has this data: { [Error: login failed] statusCode: 401 }. Is a verification from the user required or something like that for the first login? (for example email) – gyss Sep 26 '14 at 18:44

1 Answers1

1

You have to attach User-related models to your datasource first:

loopback.User.attachTo(dataSource);
loopback.AccessToken.attachTo(dataSource);
loopback.Role.attachTo(dataSource);
loopback.ACL.attachTo(dataSource);

And define the relationship between User and AccessToken:

loopback.User.hasMany(loopback.AccessToken, {as: 'accessTokens'});

When creating test data, you should wait for User.create to finish before calling User.login. (Rember, Node.js is asynchronous.)

User.create(
  {username: 'timbo', email: 'test@gmail.com', password: 'monkey123'},
  function(err, user) {
    // TODO: handle err != null
    User.login(
      {username: 'timbo', password: 'monkey123'},
      function(err, accesstoken) {
        console.log("This is the token: " + accesstoken);
      });
  });
Miroslav Bajtoš
  • 10,667
  • 1
  • 41
  • 99
  • Still gives me the following error for the created token: ReferenceError: Invalid left-hand side in assignment Do I need to create some extra tables in mysql or something? – Timbo925 Mar 10 '14 at 13:01
  • Please post your problem to LoopBack mailing list and include the full error message including the stack trace. https://groups.google.com/forum/#!forum/loopbackjs – Miroslav Bajtoš Mar 10 '14 at 16:45