@byu-trg/express-user-management v1.1.8
Express User Management
Library to extend an Express.js HTTP REST API with user management functionality. The library includes:
- PostgreSQL migrations
- Authorization middleware
- Endpoints for authentication and user management
Authorization Structure
There are four roles available that can be assigned to a user:
- Admin (role_id = 3)
- Staff (role_id = 2)
- User (role_id = 1)
- Inactive (role_id = 0)
Running PostgreSQL Migrations
This library is built to work with PostgreSQL. Migrations can be run using the following commands once the package is installed.
Migrate up
npm explore @byu-trg/express-user-management -- npm run migrate up
Migrate down
npm explore @byu-trg/express-user-management -- npm run migrate down
Authorization Middleware
verifyToken
Verifies JWT with server-side stored auth secret. Should be present on any endpoint that requires authorization.
NOTE: This middleware stores the decrypted JWT on the Express request object. Since the other middleware depend on the JWT being available on the request object, this middleware must be used first.
const verifyToken =
(
authSecret: string
) =>
(
req: Request,
res: Response,
next: NextFunction
) => {}
checkVerification
Checks that the requester has been verified via email.
const checkVerification =
(
req: Request,
res: Response,
next: NextFunction
) => {}
checkRole
Verifies that the requester has one of the inputted roles.
const checkRole =
(
roles: Role[]
) =>
(
req: Request,
res: Response,
next: NextFunction
) => {}
Extending Express app with user management endpoints
The default export of the library is a constructor function for the user management endpoints and associated dependencies. The constructor takes the Express app, a Winston logger, a Nodemailer transporter instance, as well as some other configuration variables.
Example instantiation
const app = express();
const smtpTransporter = nodemailer.createTransport({
service: smtpConfig.provider,
secure: true,
auth: {
user: smtpConfig.email,
pass: smtpConfig.password,
},
});
constructUserManagementAPI(
app,
{
logger,
smtpConfig: {
transporterConfig: smtpTransporter.transporter,
email: smtpConfig.email,
},
authConfig: {
secret: process.env.AUTH_SECRET as string
},
dbConfig: {
connectionString: dbConfig.connectionString,
ssl: process.env.APP_ENV === 'production' ? { rejectUnauthorized: false } : false,
}
}
)
Endpoints
Parameters are required unless otherwise specified.
Authentication
URL
/api/auth/signup
HTTP METHOD
POST
Params
@username @email @password @name
Responses
Status Code: 400 (Bad Request)
Body: {
message: "Body must include username, email, password, and name"
}
Status Code: 204 (Success with no content)
Body: {}
URL
/api/auth/signin
HTTP METHOD
POST
Params
@username @password
Responses
Status Code: 400 (Bad Request)
Body: {
message: "Body must include a username and password"
}
Status Code: 400 (Bad Request)
Body: {
message: "Username or password is incorrect. Please try again."
}
Status Code: 200 (Success)
Body: {
token: <User JWT>
}
URL
/api/auth/logout
HTTP METHOD
GET
Responses
Status Code: 200 (Success)
Body: {}
URL
/api/auth/verify/:token
HTTP METHOD
GET
Responses
Status Code: 302 (redirect)
Redirect URL: /login
URL
/api/auth/recovery
HTTP METHOD
POST
Params
Responses
Status Code: 400 (Bad Request)
Body: {
message: "Body must include email"
}
Status Code: 302 (Redirect)
Redirect URL: /recover/sent
URL
/api/auth/recovery/verify/:token
HTTP METHOD
POST
Params
Responses
Status Code: 400 (Bad Request)
Body: {
message: "Something went wrong on our end. Please try again."
}
Status Code: 302 (Redirect)
Redirect URL: /recover/:token
URL
/api/auth/recovery/:token
HTTP METHOD
POST
Params
@password
Responses
Status Code: 400 (Bad Request)
Body: {
message: "Body must include password"
}
Status Code: 400 (Bad Request)
Body: {
message: "Something went wrong on our end. Please try again."
}
Status Code: 200 (Success)
Body: {
token: <User JWT>;
}
User Management
User Schema:
{
user_id: UUID;
username: string;
verified: boolean;
password: string;
email: string;
name: string;
role_id: Role;
}
URL
/api/user/:id
HTTP METHOD
PATCH
Params
@username (optional) @email (optional) @name (optional) @password (optional) @roleId (optional)
Notes
For all parameters except roleId, updates will only be made if the requester is the same user as the resource.
The roleId parameter can be updated for any user as long as the requester has the Admin role.
Responses
Status Code: 400 (Bad Request)
Body: {
message: "Body must include password"
}
Status Code: 400 (Bad Request)
Body: {
message: "Something went wrong on our end. Please try again."
}
Status Code: 200 (Success)
Body: {
newToken: <User JWT>;
}
URL
/api/user/:id
HTTP METHOD
GET
Notes
User will only be retrieved if the requester is the same user as the resource.
Responses
Status Code: 400 (Bad Request)
Body: {
message: "Something went wrong on our end. Please try again."
}
Status Code: 404 (Not Found)
Body: {
message: "Resource not found"
}
Status Code: 200 (Success)
Body: {
email: string;
username: string;
name: string;
}
URL
/api/users
HTTP METHOD
GET
Allowed Roles
Admin
Responses
Status Code: 200 (Success)
Body: {
users: User[]
}
URL
/api/user/:id
HTTP METHOD
DELETE
Allowed Roles
Admin
Responses
Status Code: 204 (Success with no content)
Body: {}