fleet/website/assets/js/components/stripe-card-element.component.js

193 lines
8.3 KiB
JavaScript
Raw Normal View History

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 578a1a01ffb8404aae869e05005e30a6ba2b2a95 * 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 0d45e568f693efba7d7072085bc98d72a482d9ae hoping I was wrong in 0d45e568f693efba7d7072085bc98d72a482d9ae 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 20:48:03 +00:00
/**
* <stripe-card-element>
* -----------------------------------------------------------------------------
* A wrapper for the Stripe Elements "card" component (https://stripe.com/elements)
*
* @type {Component}
*
* @event update:busy [:busy.sync="…"]
* @event input [emitted when the stripe token changes (supports v-model)]
* @event invalidated [emitted when the field had been changed to include an invalid value]
* @event validated [emitted when the field had been changed to include a valid value]
* -----------------------------------------------------------------------------
*/
parasails.registerComponent('stripeCardElement', {
// ╦╔╗╔╔╦╗╔═╗╦═╗╔═╗╔═╗╔═╗╔═╗
// ║║║║ ║ ║╣ ╠╦╝╠╣ ╠═╣║ ║╣
// ╩╝╚╝ ╩ ╚═╝╩╚═╚ ╩ ╩╚═╝╚═╝
props: [
'stripePublishableKey',
'isErrored',
'errorMessage',//« optional custom error message to display
'value',//« the v-model passed in.
'busy',
'showExisting',// « whether to show the existing card info passed into `v-model`
],
// ╔╦╗╔═╗╦═╗╦╔═╦ ╦╔═╗
// ║║║╠═╣╠╦╝╠╩╗║ ║╠═╝
// ╩ ╩╩ ╩╩╚═╩ ╩╚═╝╩
template: `
<div>
<div v-if="existingCardData">
<span class="existing-card">{{existingCardData.billingCardBrand}} ending in <strong>{{existingCardData.billingCardLast4}}</strong></span>
<small class="new-card-text d-inline-block ml-2">(Want to use a different card ? <a class="text-primary change-card-button" type="button" @click="clickChangeExistingCard()">Click here</a>.)</small>
</div>
<div class="card-element-wrapper" :class="[existingCardData ? 'secret-card-element-wrapper' : '', isErrored ? 'is-invalid' : '']" :aria-hidden="existingCardData ? true : false">
<div class="card-element form-control" :class="isErrored ? 'is-invalid' : ''" card-element></div>
<span class="status-indicator syncing text-primary" :class="[isSyncing ? '' : 'hidden']"><span class="fa fa-spinner"></span></span>
<span class="status-indicator text-primary" :class="[isValidated ? '' : 'hidden']"><span class="fa fa-check-circle"></span></span>
<div class="invalid-feedback" v-if="!isValidated && isErrored">{{ errorMessage || 'Please check your card info.'}}</div>
</div>
</div>
`,
// ╔═╗╔╦╗╔═╗╔╦╗╔═╗
// ╚═╗ ║ ╠═╣ ║ ║╣
// ╚═╝ ╩ ╩ ╩ ╩ ╚═╝
data: function (){
return {
isSyncing: false,
isValidated: false,
existingCardData: undefined,
// The underlying Stripe instance
_stripe: undefined,
// The underlying Stripe elements instance
_elements: undefined,
// The underlying Stripe element instance this component creates as it mounts.
_element: undefined,
};
},
// ╦ ╦╔═╗╔═╗╔═╗╦ ╦╔═╗╦ ╔═╗
// ║ ║╠╣ ║╣ ║ ╚╦╝║ ║ ║╣
// ╩═╝╩╚ ╚═╝╚═╝ ╩ ╚═╝╩═╝╚═╝
beforeMount: function() {
// Initialize an instance of Stripe "elements", which we'll pass into
// our <stripe-element> component instances.
// (We also save an instance of `stripe` for use below.)
this._stripe = Stripe(this.stripePublishableKey);
this._elements = this._stripe.elements();
},
mounted: function (){
if(this.showExisting && _.isObject(this.value) && this.value.stripeToken && this.value.billingCardBrand && this.value.billingCardLast4) {
this.existingCardData = _.extend({}, this.value);
}
this._element = this._elements.create('card', {
// Classes
// > https://stripe.com/docs/js/elements_object/create_element?type=card#elements_create-options-classes
classes: {
// When the iframe is focused, attach the "pseudofocused" class
// to our wrapper <div>.
focus: 'pseudofocused'
},
// iframe styles:
// > https://stripe.com/docs/js/appendix/style?type=card
// You can update this section to match your website's theme
style: {
base: {
lineHeight: '36px',
fontSize: '16px',
Add customer portal and license dispenser to fleetdm.com (#3546) * Add images for customer portal, dashboard, and email templates * updated email layout and reset password template, new email template * update ajax-button component to have an optional spinner * updated cloud-error & stripe-card-element component styles * updates to user model, add quote and subscription * Login, signup, forgot password, update profile * link to customer portal from pricing * new-license page, bootstrap updates * create quote action, dashboard page, update routes * Add new page styles to importer, update component styles * updates to js-timestamp * update modal styles and layout * using @submitted on ajax form, controller updates * Update create-quote.js * updates to quote model, action updates, truncate license key on dashboard * update email layout, subscribe action, user model * Update importer.less * style updates, order confirmation * use correct font * style updates * create license key * new-license page changes * signup page changes * add billing format to js-timestamp component, dashboard updates, change password * swap get started link for customers * order -> subscription * Update login.ejs * Lint fixes, page updates, mobile styles * remove edit-profile route, update layout, bootstrap, forms * change customer-layout name to match other layout names, update copyright year in layouts * changes requested from code review and #3570 * submit button width, contact font-size * Update dashboard.less * Update bootstrap-overrides.less * slack logo update, login text
2022-01-05 02:02:42 +00:00
color: '#192147',
iconColor: '#6A67FE',
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 578a1a01ffb8404aae869e05005e30a6ba2b2a95 * 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 0d45e568f693efba7d7072085bc98d72a482d9ae hoping I was wrong in 0d45e568f693efba7d7072085bc98d72a482d9ae 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 20:48:03 +00:00
fontFamily: '-apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif',
'::placeholder': {
Add customer portal and license dispenser to fleetdm.com (#3546) * Add images for customer portal, dashboard, and email templates * updated email layout and reset password template, new email template * update ajax-button component to have an optional spinner * updated cloud-error & stripe-card-element component styles * updates to user model, add quote and subscription * Login, signup, forgot password, update profile * link to customer portal from pricing * new-license page, bootstrap updates * create quote action, dashboard page, update routes * Add new page styles to importer, update component styles * updates to js-timestamp * update modal styles and layout * using @submitted on ajax form, controller updates * Update create-quote.js * updates to quote model, action updates, truncate license key on dashboard * update email layout, subscribe action, user model * Update importer.less * style updates, order confirmation * use correct font * style updates * create license key * new-license page changes * signup page changes * add billing format to js-timestamp component, dashboard updates, change password * swap get started link for customers * order -> subscription * Update login.ejs * Lint fixes, page updates, mobile styles * remove edit-profile route, update layout, bootstrap, forms * change customer-layout name to match other layout names, update copyright year in layouts * changes requested from code review and #3570 * submit button width, contact font-size * Update dashboard.less * Update bootstrap-overrides.less * slack logo update, login text
2022-01-05 02:02:42 +00:00
color: '#515774',
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 578a1a01ffb8404aae869e05005e30a6ba2b2a95 * 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 0d45e568f693efba7d7072085bc98d72a482d9ae hoping I was wrong in 0d45e568f693efba7d7072085bc98d72a482d9ae 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 20:48:03 +00:00
},
},
invalid: {
Add customer portal and license dispenser to fleetdm.com (#3546) * Add images for customer portal, dashboard, and email templates * updated email layout and reset password template, new email template * update ajax-button component to have an optional spinner * updated cloud-error & stripe-card-element component styles * updates to user model, add quote and subscription * Login, signup, forgot password, update profile * link to customer portal from pricing * new-license page, bootstrap updates * create quote action, dashboard page, update routes * Add new page styles to importer, update component styles * updates to js-timestamp * update modal styles and layout * using @submitted on ajax form, controller updates * Update create-quote.js * updates to quote model, action updates, truncate license key on dashboard * update email layout, subscribe action, user model * Update importer.less * style updates, order confirmation * use correct font * style updates * create license key * new-license page changes * signup page changes * add billing format to js-timestamp component, dashboard updates, change password * swap get started link for customers * order -> subscription * Update login.ejs * Lint fixes, page updates, mobile styles * remove edit-profile route, update layout, bootstrap, forms * change customer-layout name to match other layout names, update copyright year in layouts * changes requested from code review and #3570 * submit button width, contact font-size * Update dashboard.less * Update bootstrap-overrides.less * slack logo update, login text
2022-01-05 02:02:42 +00:00
color: '#FF5C83',
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 578a1a01ffb8404aae869e05005e30a6ba2b2a95 * 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 0d45e568f693efba7d7072085bc98d72a482d9ae hoping I was wrong in 0d45e568f693efba7d7072085bc98d72a482d9ae 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 20:48:03 +00:00
},
},
});
this._element.mount($(this.$el).find('[card-element]')[0]);
// When a change occurs, immediately clear the token by
// emitting an input event with '', show a loading spinner, and start
// fetching a new token. Then in userland, the validation error for a missing
// card becomes something reasonable that implies that we may not have finished
// getting it yet, so hold your horses.
this._element.on('change', (stripeEvent)=> {
// If there is an error, set the v-model to be empty.
if(stripeEvent.error) {
this.$emit('input', '');
} else if(stripeEvent.complete) {
// If the field is complete, (aka valid), fetch a token and set that on the v-model
// (first clearing out the v-model, so this won't be considered valid yet e.g. if it was just changed.
if(this.isSyncing) { return; }
this.$emit('');
this.isSyncing = true;
this.$emit('update:busy', true);
this.isValidated = false;
this._fetchNewToken();
} else {
// FUTURE: possibly handle other events, if necessary.
}//fi
});//œ
},
beforeDestroy: function (){
// Note: There isn't any documented way to tear down a `stripe` instance.
// Same thing for the `elements` instance. Only individual "element" instances
// can be cleaned up after, using `.unmount()`.
this._element.unmount();
},
// ╔═╗╦ ╦╔═╗╔╗╔╔╦╗╔═╗
// ║╣ ╚╗╔╝║╣ ║║║ ║ ╚═╗
// ╚═╝ ╚╝ ╚═╝╝╚╝ ╩ ╚═╝
methods: {
clickChangeExistingCard: function() {
this.existingCardData = undefined;
this.$emit('input', '');
},
// Public method for fetching a fresh token (e.g. if card is declined)
doGetNewToken: function() {
this.isSyncing = true;
this.$emit('update:busy', true);
this.isValidated = false;
this.$emit('input', '');
this._fetchNewToken();
},
_fetchNewToken: function() {
this._getStripeTokenFromCardElement(this._stripe, this._element)
.then((paymentSourceInfo)=>{
this.isSyncing = false;
this.$emit('update:busy', false);
this.isValidated = true;
this.$emit('input', paymentSourceInfo);
}).catch((err)=>{
this.isSyncing = false;
this.$emit('update:busy', false);
this.isValidated = false;
// This error is only relevant if something COMPLETELY unexpected goes wrong,
// in which case we want to actually know about that.
throw err;
});//_∏_
},
_getStripeTokenFromCardElement: function(stripeInstance, stripeElement) {
// Build a Promise & send it back as our "thenable" (AsyncFunction's return value).
// (this is necessary b/c we're wrapping an api that isn't `await`-compatible)
return new Promise((resolve, reject)=>{
try {
// Create a stripe token using the Stripe "element".
stripeInstance.createToken(stripeElement)
.then((result)=>{
// Silently ignore the case where the field is empty, or if there are
// card validation issues.
if(!result || result.error) {
resolve();
return;
}
// Send back the token & payment info.
resolve({
stripeToken: result.token.id,
billingCardBrand: result.token.card.brand,
billingCardLast4: result.token.card.last4,
billingCardExpMonth: result.token.card.exp_month,
billingCardExpYear: result.token.card.exp_year
});
});
} catch (err) {
console.error('Could not obtain Stripe token:', err);
reject(err);
}
});//_∏_
}
}
});