fleet/website/api/models/User.js
Mike McNeil 27eae209fd
Move fleetdm.com into main Fleet repo (#83)
* rename dir

* no need to install website or docs from npm

At some point, would also be nice to be able to exclude assets/ as well, and to only install a pre-built version of Fleet's frontend code

* Bring in fleetdm.com website

From https://github.com/fleetdm/fleetdm.com as of https://github.com/fleetdm/fleetdm.com/releases/tag/v0.0.21

* add procfile for heroku

Using https://github.com/timanovsky/subdir-heroku-buildpack

* avoid getting anybody's hopes up

* Create deploy-fleet-website.yml (#82)

* Create deploy-fleet-website.yml

* Update deploy-fleet-website.yml

* Update deploy-fleet-website.yml

* Update deploy-fleet-website.yml

* update pjs with SPDX-like license expressions.  also fix repo URL

and remove package lock

* Update deploy-fleet-website.yml

* Update deploy-fleet-website.yml

* remove dummy uri

* Dissect deploy script

* Update deploy-fleet-website.yml

* workaround for eslintrc nesting issue

* lint fixes

* forgot the .js

* add per-commit git config

* Update deploy-fleet-website.yml

* might as well remove that

* cleanup

* connect w/ heroku app and have it actually push

* fix bug I introduced in 578a1a01ff

* Update deploy-fleet-website.yml

* Update deploy-fleet-website.yml

* Update deploy-fleet-website.yml

* Update deploy-fleet-website.yml

* the beauty, the glory, of javascript

* GH actions don't like "\n"

* Update deploy-fleet-website.yml

* restore \n chars from 0d45e568f6

hoping I was wrong in 0d45e568f6 but see also https://github.community/t/what-is-the-correct-character-escaping-for-workflow-command-values-e-g-echo-xxxx/118465/5

* Update deploy-fleet-website.yml

* Update deploy-fleet-website.yml

* Update deploy-fleet-website.yml

* Update deploy-fleet-website.yml

* Update deploy-fleet-website.yml

* Update deploy-fleet-website.yml

* Update deploy-fleet-website.yml

* Update deploy-fleet-website.yml

* Update deploy-fleet-website.yml

* Update deploy-fleet-website.yml

* Update deploy-fleet-website.yml

* Update deploy-fleet-website.yml

* rename script to prevent duplicate building

* Configure the real website

* clean up

* a test of the deploy workflow

* add handbook to npmignore

* I guess you could call this fixing a typo

* point workflow at master branch

* now clearly bogus: this completely unused version string
2020-12-02 14:48:03 -06:00

171 lines
7.1 KiB
JavaScript

/**
* User.js
*
* A user who can log in to this application.
*/
module.exports = {
attributes: {
// ╔═╗╦═╗╦╔╦╗╦╔╦╗╦╦ ╦╔═╗╔═╗
// ╠═╝╠╦╝║║║║║ ║ ║╚╗╔╝║╣ ╚═╗
// ╩ ╩╚═╩╩ ╩╩ ╩ ╩ ╚╝ ╚═╝╚═╝
emailAddress: {
type: 'string',
required: true,
unique: true,
isEmail: true,
maxLength: 200,
example: '[email protected]'
},
emailStatus: {
type: 'string',
isIn: ['unconfirmed', 'change-requested', 'confirmed'],
defaultsTo: 'confirmed',
description: 'The confirmation status of the user\'s email address.',
extendedDescription:
`Users might be created as "unconfirmed" (e.g. normal signup) or as "confirmed" (e.g. hard-coded
admin users). When the email verification feature is enabled, new users created via the
signup form have \`emailStatus: 'unconfirmed'\` until they click the link in the confirmation email.
Similarly, when an existing user changes their email address, they switch to the "change-requested"
email status until they click the link in the confirmation email.`
},
emailChangeCandidate: {
type: 'string',
isEmail: true,
description: 'A still-unconfirmed email address that this user wants to change to (if relevant).'
},
password: {
type: 'string',
required: true,
description: 'Securely hashed representation of the user\'s login password.',
protect: true,
example: '2$28a8eabna301089103-13948134nad'
},
fullName: {
type: 'string',
required: true,
description: 'Full representation of the user\'s name.',
maxLength: 120,
example: 'Mary Sue van der McHenst'
},
isSuperAdmin: {
type: 'boolean',
description: 'Whether this user is a "super admin" with extra permissions, etc.',
extendedDescription:
`Super admins might have extra permissions, see a different default home page when they log in,
or even have a completely different feature set from normal users. In this app, the \`isSuperAdmin\`
flag is just here as a simple way to represent two different kinds of users. Usually, it's a good idea
to keep the data model as simple as possible, only adding attributes when you actually need them for
features being built right now.
For example, a "super admin" user for a small to medium-sized e-commerce website might be able to
change prices, deactivate seasonal categories, add new offerings, and view live orders as they come in.
On the other hand, for an e-commerce website like Walmart.com that has undergone years of development
by a large team, those administrative features might be split across a few different roles.
So, while this \`isSuperAdmin\` demarcation might not be the right approach forever, it's a good place to start.`
},
passwordResetToken: {
type: 'string',
description: 'A unique token used to verify the user\'s identity when recovering a password. Expires after 1 use, or after a set amount of time has elapsed.'
},
passwordResetTokenExpiresAt: {
type: 'number',
description: 'A JS timestamp (epoch ms) representing the moment when this user\'s `passwordResetToken` will expire (or 0 if the user currently has no such token).',
example: 1502844074211
},
emailProofToken: {
type: 'string',
description: 'A pseudorandom, probabilistically-unique token for use in our account verification emails.'
},
emailProofTokenExpiresAt: {
type: 'number',
description: 'A JS timestamp (epoch ms) representing the moment when this user\'s `emailProofToken` will expire (or 0 if the user currently has no such token).',
example: 1502844074211
},
stripeCustomerId: {
type: 'string',
protect: true,
description: 'The id of the customer entry in Stripe associated with this user (or empty string if this user is not linked to a Stripe customer -- e.g. if billing features are not enabled).',
extendedDescription:
`Just because this value is set doesn't necessarily mean that this user has a billing card.
It just means they have a customer entry in Stripe, which might or might not have a billing card.`
},
hasBillingCard: {
type: 'boolean',
description: 'Whether this user has a default billing card hooked up as their payment method.',
extendedDescription:
`More specifically, this indcates whether this user record's linked customer entry in Stripe has
a default payment source (i.e. credit card). Note that a user have a \`stripeCustomerId\`
without necessarily having a billing card.`
},
billingCardBrand: {
type: 'string',
example: 'Visa',
description: 'The brand of this user\'s default billing card (or empty string if no billing card is set up).',
extendedDescription: 'To ensure PCI compliance, this data comes from Stripe, where it reflects the user\'s default payment source.'
},
billingCardLast4: {
type: 'string',
example: '4242',
description: 'The last four digits of the card number for this user\'s default billing card (or empty string if no billing card is set up).',
extendedDescription: 'To ensure PCI compliance, this data comes from Stripe, where it reflects the user\'s default payment source.'
},
billingCardExpMonth: {
type: 'string',
example: '08',
description: 'The two-digit expiration month from this user\'s default billing card, formatted as MM (or empty string if no billing card is set up).',
extendedDescription: 'To ensure PCI compliance, this data comes from Stripe, where it reflects the user\'s default payment source.'
},
billingCardExpYear: {
type: 'string',
example: '2023',
description: 'The four-digit expiration year from this user\'s default billing card, formatted as YYYY (or empty string if no credit card is set up).',
extendedDescription: 'To ensure PCI compliance, this data comes from Stripe, where it reflects the user\'s default payment source.'
},
tosAcceptedByIp: {
type: 'string',
description: 'The IP (ipv4) address of the request that accepted the terms of service.',
extendedDescription: 'Useful for certain types of businesses and regulatory requirements (KYC, etc.)',
moreInfoUrl: 'https://en.wikipedia.org/wiki/Know_your_customer'
},
lastSeenAt: {
type: 'number',
description: 'A JS timestamp (epoch ms) representing the moment at which this user most recently interacted with the backend while logged in (or 0 if they have not interacted with the backend at all yet).',
example: 1502844074211
},
// ╔═╗╔╦╗╔╗ ╔═╗╔╦╗╔═╗
// ║╣ ║║║╠╩╗║╣ ║║╚═╗
// ╚═╝╩ ╩╚═╝╚═╝═╩╝╚═╝
// n/a
// ╔═╗╔═╗╔═╗╔═╗╔═╗╦╔═╗╔╦╗╦╔═╗╔╗╔╔═╗
// ╠═╣╚═╗╚═╗║ ║║ ║╠═╣ ║ ║║ ║║║║╚═╗
// ╩ ╩╚═╝╚═╝╚═╝╚═╝╩╩ ╩ ╩ ╩╚═╝╝╚╝╚═╝
// n/a
},
};