Git Product home page Git Product logo

api-server-nodejs's Introduction

Express/Nodejs Starter with JWT Authentication, OAuth (Github), and SQLite persistence - Provided by AppSeed. Authentication Flow uses json web tokens via Passport library - passport-jwt strategy.

๐Ÿ‘‰ Support via Discord & Email provided by AppSeed.


Features

  • ๐Ÿš€ Full-stack ready with React Soft Dashboard
  • โœ… Simple, intuitive codebase - can be extended with ease.
  • โœ… TypeScript, Joy for validation
  • โœ… Stack: NodeJS / Express / SQLite / TypeORM
  • โœ… Auth: Passport / passport-jwt strategy
  • ๐Ÿ†• OAuth for Github

Tested with:

NodeJS NPM YARN
v18.0.0 โœ… โœ…
v16.10.0 โœ… โœ…
v14.15.0 โœ… โœ…

Nodejs API Server - Open-source Nodejs Starter provided by AppSeed.


โœจ Requirements


โœจ How to use the code

๐Ÿ‘‰ Step 1 - Clone the project

$ git clone https://github.com/app-generator/api-server-nodejs.git
$ cd api-server-nodejs

๐Ÿ‘‰ Step 2 - Install dependencies via Yarn

$ npm i
// OR 
$ yarn

๐Ÿ‘‰ Step 3 - Run the SQLite migration via TypeORM

$ npm run typeorm migration:run
// OR 
$ yarn typeorm migration:run

๐Ÿ‘‰ Step 4 - Edit the .env using the template .env.sample.

PORT=5000                       # API PORT
SQLITE_PATH=./database.db       # Path to the SQLite database file
SECRET="Whatever-STRONG"        # Secret for sensitive data hashing 

# Same as for React APP
GITHUB_OAUTH_CLIENT_ID= ...     # Github OAuth secret 
GITHUB_OAUTH_CLIENT_SECRET= ... # Github OAuth secret

๐Ÿ‘‰ Step 5 - Start the API server (development mode)

$ npm run dev
// OR
$ yarn dev

๐Ÿ‘‰ Step 6 - Production Build (files generated in build directory)

$ yarn build

๐Ÿ‘‰ Step 7 - Start the API server for production (files served from build/index.js)

$ yarn start

The API server will start using the PORT specified in .env file (default 5000).


โœจ Codebase Structure

< ROOT / src >
     | 
     |-- config/                              
     |    |-- config.ts             # Configuration       
     |    |-- passport.ts           # Define Passport Strategy             
     | 
     |-- migration/
     |    |-- some_migration.ts     # database migrations
     |
     |-- models/                              
     |    |-- activeSession.ts      # Sessions Model (Typeorm)              
     |    |-- user.ts               # User Model (Typeorm) 
     | 
     |-- routes/                              
     |    |-- users.ts              # Define Users API Routes
     | 
     | 
     |-- index.js                   # API Entry Point
     |-- .env                       # Specify the ENV variables
     |                        
     |-- ************************************************************************

โœจ SQLite Path

The SQLite Path is set in .env, as SQLITE_PATH


โœจ Database migration

๐Ÿ‘‰ Generate migration:

$ yarn typeorm migration:generate -n your_migration_name

๐Ÿ‘‰ Run migration:

$ yarn typeorm migration:run

โœจ API

For a fast set up, use this POSTMAN file: api_sample

๐Ÿ‘‰ Register - api/users/register

POST api/users/register
Content-Type: application/json

{
    "username":"test",
    "password":"pass", 
    "email":"[email protected]"
}

๐Ÿ‘‰ Login - api/users/login

POST /api/users/login
Content-Type: application/json

{
    "password":"pass", 
    "email":"[email protected]"
}

๐Ÿ‘‰ Logout - api/users/logout

POST api/users/logout
Content-Type: application/json
authorization: JWT_TOKEN (returned by Login request)

{
    "token":"JWT_TOKEN"
}

โœจ Update role for existing user

๐Ÿ‘‰ Using npm:

$ npm run update-role [user_id] [role_id (optional)]


๐Ÿ‘‰ Using yarn:

$ yarn update-role [user_id] [role_id (optional)]

  • [user_id] is the id of existing user to update role for.
  • [role_id] is the id of role: 1 for admin & 2 for user. If you don't provide any role_id it would update user to admin role.

โœจ Run the Tests (minimal suite)

$ npm run test
// OR
$ yarn test

โœจ Credits

This software is provided by the core AppSeed team with an inspiration from other great NodeJS starters:



Node JS API Server - provided by AppSeed App Generator

api-server-nodejs's People

Contributors

app-generator avatar fullstackkdev avatar natelindev avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

api-server-nodejs's Issues

Typescript Migration - Tests are failing

Symptom

After typescript migration, yarn test target fails with error:

SyntaxError: Cannot use import statement outside a module

Full Error Log

yarn test
yarn run v1.22.5
$ jest -i --colors --verbose --detectOpenHandles
 FAIL  tests/basic.test.ts
  โ— Test suite failed to run

    Jest encountered an unexpected token

    Jest failed to parse a file. This happens e.g. when your code or its dependencies use non-standard JavaScript syntax, or when Jest is not configured to support such syntax.

    Out of the box Jest supports Babel, which will be used to transform your files into valid JS based on your Babel configuration.

    By default "node_modules" folder is ignored by transformers.

    Here's what you can do:
     โ€ข If you are trying to use ECMAScript Modules, see https://jestjs.io/docs/ecmascript-modules for how to enable it.
     โ€ข To have some of your "node_modules" files transformed, you can specify a custom "transformIgnorePatterns" in your config.
     โ€ข If you need a custom transformation specify a "transform" option in your config.
     โ€ข If you simply want to mock your non-JS modules (e.g. binary assets) you can stub them out with the "moduleNameMapper" config option.

    You'll find more details and examples of these config options in the docs:
    https://jestjs.io/docs/configuration
    For information about custom transformations, see:
    https://jestjs.io/docs/code-transformation

    Details:

    D:\work\repo-api-servers\api-server-nodejs\tests\basic.test.ts:6
    import request from 'supertest';
    ^^^^^^

    SyntaxError: Cannot use import statement outside a module

      at Runtime.createScriptFromCode (node_modules/jest-runtime/build/index.js:1479:14)
      at TestScheduler.scheduleTests (node_modules/@jest/core/build/TestScheduler.js:333:13)

passport authentication always returns missing credentials

`router.post('/login', auth.optional, (req, res, next) => {
const { body: { user } } = req;
console.log(req.body);
const result = Joi.validate(user, userSchema);

if (result.error) {
	return res.status(422).json({
		errors: result.error
	});
}
console.log('login');
return passport.authenticate('local', { session: false }, (err, passportUser, info) => {
	console.log(err);
	console.log(info);
	if (err) {
		return next(err);
	}

	console.log(passportUser);

	if (passportUser) {
		const user = {
			_id: passportUser.id,
			email: passportUser.email,
			name: passportUser.name,
			surname: passportUser.surname,
			token: generateJWT(passportUser)
		};

		return res.json({ user });
	}

	return res.status(400).send(info);
})(req, res, next);

});`

passport.authenticate always says missing credentials. From the call back err is set to null, user is set to false and info is set to missing credentials. I searched stackoverflow and google but could not find a solution. It always returns missing credentials.

Change database

Did anyone change the database to something else, like MongoDB or PostgreSQL?

Typescript Migration - Runtime Error / Expected "payload" to be a plain object

Symptom

During the http://localhost:5000/api/users/login request, the server bumps runtime error:

Expected "payload" to be a plain object

Full error log:

yarn dev  
yarn run v1.22.5
$ ts-node-dev src/index.ts
[INFO] 08:06:11 ts-node-dev ver. 1.1.8 (using ts-node ver. 9.1.1, typescript ver. 4.3.5)
Server is listening on port 5000
MongoDB Connected
Error: Expected "payload" to be a plain object.
    at validate (D:\work\repo-api-servers\api-server-nodejs\node_modules\jsonwebtoken\sign.js:40:11)
    at validatePayload (D:\work\repo-api-servers\api-server-nodejs\node_modules\jsonwebtoken\sign.js:62:10)
    at Object.module.exports [as sign] (D:\work\repo-api-servers\api-server-nodejs\node_modules\jsonwebtoken\sign.js:114:7)
    at D:\work\repo-api-servers\api-server-nodejs\src\routes\users.ts:90:27
    at D:\work\repo-api-servers\api-server-nodejs\node_modules\bcrypt-nodejs\bCrypt.js:689:3
    at processTicksAndRejections (internal/process/task_queues.js:79:11)
[ERROR] 08:06:22 Error: Expected "payload" to be a plain object.

Expected behaviour

Have a successful login.

Docker / Mongo Error: `users.findOne()` buffering timed out after 10000ms

Connection with Mongo inside docker bumps a timeout error.

Mongo seems to start without errors

mongodb_1            | 2021-07-05T07:57:11.163+0000 I  SHARDING [LogicalSessionCacheReap] Marking collection config.transactions as collection version: <unsharded>
mongodb_1            | 2021-07-05T07:57:11.163+0000 I  NETWORK  [initandlisten] Listening on 0.0.0.0
mongodb_1            | 2021-07-05T07:57:11.163+0000 I  NETWORK  [initandlisten] waiting for connections on port 27017

At first request, a timeout is fired:

api-server-nodejs_1  | App listening on port 5000! Go to http://localhost:5000/
api-server-nodejs_1  | /usr/src/api-server-nodejs/node_modules/mongoose/lib/drivers/node-mongodb-native/collection.js:197
api-server-nodejs_1  |           const err = new MongooseError(message);
api-server-nodejs_1  |                       ^
api-server-nodejs_1  |
api-server-nodejs_1  | MongooseError: Operation `users.findOne()` buffering timed out after 10000ms
api-server-nodejs_1  |     at Timeout.<anonymous> (/usr/src/api-server-nodejs/node_modules/mongoose/lib/drivers/node-mongodb-native/collection.js:197:23)
api-server-nodejs_1  |     at listOnTimeout (node:internal/timers:557:17)
api-server-nodejs_1  |     at processTimers (node:internal/timers:500:7)

Default User Role - Save NULL Value

On Creation, the user should be assigned to the "USER" role = value 2

Currently, the users are created with a NULL value for the ROLE column.

Here is the response to the registration request:

{
    "success": true,
    "token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpZCI6ImE2Nzc4NDViLTEwODctNDliOS05N2I1LTlkYzM1YWFlYTE0YyIsInVzZXJuYW1lIjoidGVzdCIsImVtYWlsIjoidGVzdEBhcHBzZWVkLnVzIiwiaWF0IjoxNjY5NzM1NTczLCJleHAiOjE2Njk4MjE5NzN9.9Lg4Ryw75xLd4iOl-V3Pp-lx9rt6zjXfc5DYTCYhvYQ",
    "user": {
        "id": "a677845b-1087-49b9-97b5-9dc35aaea14c",
        "username": "test",
        "email": "[email protected]",
        "date": "2022-11-29T15:21:51.000Z",
        "user_role": null
    }
}

SQLite migration via TypeORM Missing required argument: dataSource

OS: MacOS 14.1.1 (23B81) AND Ubuntu 22.04
Node Version: 16, 18, and 20

When running the following during step 3 of the installation:
$ npm run typeorm migration:run
// OR
$ yarn typeorm migration:run

I get the following error on multiple OSs and versions of node:

npm run typeorm migration:run

[email protected] typeorm
node --require ts-node/register ./node_modules/typeorm/cli.js migration:run

cli.js migration:run

Runs all pending migrations.

Options:
-h, --help Show help [boolean]
-d, --dataSource Path to the file where your DataSource instance is defined.
[required]
-t, --transaction Indicates if transaction should be used or not for
migration run. Enabled by default. [default: "default"]
-f, --fake Fakes running the migrations if table schema has already
been changed manually or externally (e.g. through another
project) [boolean] [default: false]
-v, --version Show version number [boolean]

Missing required argument: dataSource

ROLE column - Wrong Type Used

Hello @FullStackkDev

The Role column should use integer type for values.

Impacted tables:

USER: user_role -> integer, default value 2 (user type)

CREATE TABLE "user" ("id" varchar PRIMARY KEY NOT NULL, "username" text NOT NULL, "email" text, "password" text, "user_role" varchar, "date" datetime NOT NULL DEFAULT (CURRENT_TIMESTAMP))

ROLE: ID column -> integer (now is varchar)

"role" ("id" varchar PRIMARY KEY NOT NULL, "name" text NOT NULL, "date" datetime NOT NULL DEFAULT (CURRENT_TIMESTAMP))

Please take a look.
Ty!

Tests / Register - Expected I/O

API URL : http://localhost:5000/api/users/register

Request Headers

  • Content-Type: application/json

Request Body

{
    "username":"test",
    "password":"pass", 
    "email":"[email protected]"
}

Response for success

{
    "success": true,
    "userID": "1",
    "msg": "The user was succesfully registered"
}

Response for error - email already taken

{
    "success": false,
    "msg": "Email already taken"
}

Evolution 2# - OAuth for GitHub

Hello @FullStackkDev!

The API should be enhanced to support OAuth via Github.

Requirements:

  • the backward compatibility assured:
    • JWT Login
    • existing API signature
  • The library used in NodeJS should be actively supported and alive
    • Please propose a few options here

Ty!

Evolution 3# - Authorization (Roles)

Hello @FullStackkDev

The authorization should link each user to a ROLE:

  • user - numeric value 1 in users table
  • admin - numeric value 2 in users table

On successful signIN (JWT) or OAuth, the API server return also the role of the user

  • during the registration (JWT, OAuth) the created user is associated with a default "USER" role

Thank you!

Quality Check

This is not a real issue. Is just a tracker for the rules applied during the coding phase.

  • code should be kept simple
  • typescript
  • modular
  • if something is not clear, please ask

Thank you!

start server side

https://github.com/app-generator/api-server-nodejs

need to start the server and point to the client to this server (Where do I change the API url in env?)

I've the client under the folder:
C:\Users\nuno.lopes#Work\Projects\pro>


Log:
C:\Users\nuno.lopes#Work\Projects\pro_server>npm install
npm WARN config global --global, --local are deprecated. Use --location=global instead.
npm WARN deprecated [email protected]: this library is no longer supported
npm WARN deprecated [email protected]: Please upgrade to version 7 or higher. Older versions may use Math.random() in certain circumstances, which is known to be problematic. See https://v8.dev/blog/math-random for details.
npm WARN deprecated [email protected]: request has been deprecated, see request/request#3142
npm WARN deprecated [email protected]: The library contains critical security issues and should not be used for production! The maintenance of the project has been discontinued. Consider migrating your code to isolated-vm.
npm WARN deprecated [email protected]: Please upgrade to @mapbox/node-pre-gyp: the non-scoped node-pre-gyp package is deprecated and only the @mapbox scoped package will recieve updates in the future
npm WARN deprecated [email protected]: This version of tar is no longer supported, and will not receive security updates. Please upgrade asap.

added 958 packages, and audited 959 packages in 37s

119 packages are looking for funding
run npm fund for details

18 vulnerabilities (9 moderate, 3 high, 6 critical)

To address issues that do not require attention, run:
npm audit fix

To address all issues (including breaking changes), run:
npm audit fix --force

Run npm audit for details.

C:\Users\nuno.lopes#Work\Projects\pro_server>npm start
npm WARN config global --global, --local are deprecated. Use --location=global instead.

[email protected] start
pm2 start production.config.json

                    -------------

/\\\\\\_/\\/\\/\\\\_
_/\/////////\_/\\\
/\\\/\///////\_
/\_
/\_/\//\_/\//\_/////\_
_/\\\\\\/
/\\///\/\/
/\_
/\/
/\/////////
/\_
///\/
/\_/\//_____
/\_
/\_////\_____/\//_____
/\_/\_/\_/\/__________
/\_/\_/\_/\\\\\\\_
_////////////////////////

                      Runtime Edition

    PM2 is a Production Process Manager for Node.js applications
                 with a built-in Load Balancer.

            Start and Daemonize any application:
            $ pm2 start app.js

            Load Balance 4 instances of api.js:
            $ pm2 start api.js -i 4

            Monitor in production:
            $ pm2 monitor

            Make pm2 auto-boot at server restart:
            $ pm2 startup

            To go further checkout:
            http://pm2.io/


                    -------------

[PM2] Spawning PM2 daemon with pm2_home=C:\Users\nuno.lopes.pm2
[PM2] PM2 Successfully daemonized
[PM2][WARN] Applications nodejs_api not running, starting...
[PM2][ERROR] Error: Script not found: C:\Users\nuno.lopes#Work\Projects\pro_server\build\index.js

Error when installing modules

I am getting many errors when i call npm i
I just downloaded the repo and run the command. Please update me if you require any log or other info.

37 warnings and 13 errors generated.
make:  [Release/obj.target/node_sqlite3/src/database.o] Error 1
gyp ERR! build error 
gyp ERR! stack Error: make failed with exit code: 2
gyp ERR! stack     at ChildProcess.onExit (/usr/local/lib/node_modules/npm/node_modules/node-gyp/lib/build.js:194:23)
gyp ERR! stack     at ChildProcess.emit (events.js:310:20)
gyp ERR! stack     at Process.ChildProcess._handle.onexit (internal/child_process.js:275:12)
gyp ERR! System Darwin 19.4.0
gyp ERR! command "/usr/local/bin/node" "/usr/local/lib/node_modules/npm/node_modules/node-gyp/bin/node-gyp.js" "build" "--fallback-to-build" "--module=/Users/alkhamisah/Documents/Projects/NodeJSProjects/Apify/node_modules/sqlite3/lib/binding/node-v72-darwin-x64/node_sqlite3.node" "--module_name=node_sqlite3" "--module_path=/Users/alkhamisah/Documents/Projects/NodeJSProjects/Apify/node_modules/sqlite3/lib/binding/node-v72-darwin-x64" "--napi_version=5" "--node_abi_napi=napi" "--napi_build_version=0" "--node_napi_label=node-v72"
gyp ERR! cwd /Users/alkhamisah/Documents/Projects/NodeJSProjects/Apify/node_modules/sqlite3
gyp ERR! node -v v12.16.2
gyp ERR! node-gyp -v v5.1.0
gyp ERR! not ok 
node-pre-gyp ERR! build error 
node-pre-gyp ERR! stack Error: Failed to execute '/usr/local/bin/node /usr/local/lib/node_modules/npm/node_modules/node-gyp/bin/node-gyp.js build --fallback-to-build --module=/Users/alkhamisah/Documents/Projects/NodeJSProjects/Apify/node_modules/sqlite3/lib/binding/node-v72-darwin-x64/node_sqlite3.node --module_name=node_sqlite3 --module_path=/Users/alkhamisah/Documents/Projects/NodeJSProjects/Apify/node_modules/sqlite3/lib/binding/node-v72-darwin-x64 --napi_version=5 --node_abi_napi=napi --napi_build_version=0 --node_napi_label=node-v72' (1)
node-pre-gyp ERR! stack     at ChildProcess.<anonymous> (/Users/alkhamisah/Documents/Projects/NodeJSProjects/Apify/node_modules/node-pre-gyp/lib/util/compile.js:83:29)
node-pre-gyp ERR! stack     at ChildProcess.emit (events.js:310:20)
node-pre-gyp ERR! stack     at maybeClose (internal/child_process.js:1021:16)
node-pre-gyp ERR! stack     at Process.ChildProcess._handle.onexit (internal/child_process.js:286:5)
node-pre-gyp ERR! System Darwin 19.4.0
node-pre-gyp ERR! command "/usr/local/bin/node" "/Users/alkhamisah/Documents/Projects/NodeJSProjects/Apify/node_modules/.bin/node-pre-gyp" "install" "--fallback-to-build"
node-pre-gyp ERR! cwd /Users/alkhamisah/Documents/Projects/NodeJSProjects/Apify/node_modules/sqlite3
node-pre-gyp ERR! node -v v12.16.2
node-pre-gyp ERR! node-pre-gyp -v v0.11.0
node-pre-gyp ERR! not ok 
Failed to execute '/usr/local/bin/node /usr/local/lib/node_modules/npm/node_modules/node-gyp/bin/node-gyp.js build --fallback-to-build --module=/Users/alkhamisah/Documents/Projects/NodeJSProjects/Apify/node_modules/sqlite3/lib/binding/node-v72-darwin-x64/node_sqlite3.node --module_name=node_sqlite3 --module_path=/Users/alkhamisah/Documents/Projects/NodeJSProjects/Apify/node_modules/sqlite3/lib/binding/node-v72-darwin-x64 --napi_version=5 --node_abi_napi=napi --napi_build_version=0 --node_napi_label=node-v72' (1)
npm WARN [email protected] requires a peer of ajv@^5.0.0 but none is installed. You must install peer dependencies yourself.
npm WARN [email protected] No repository field.

npm ERR! code ELIFECYCLE
npm ERR! errno 1
npm ERR! [email protected] install: "node-pre-gyp install --fallback-to-build"
npm ERR! Exit status 1
npm ERR! 
npm ERR! Failed at the [email protected] install script.
npm ERR! This is probably not a problem with npm. There is likely additional logging output above.

npm ERR! A complete log of this run can be found in:
npm ERR!     /Users/alkhamisah/.npm/_logs/2020-04-25T20_16_58_237Z-debug.log

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.