satellite/web: add segmentio plugin (#3405)

This commit is contained in:
Malcolm Bouzi 2019-11-27 11:57:59 -05:00 committed by Yingrong Zhao
parent f83837bb03
commit 18a5e614d9
11 changed files with 103 additions and 23 deletions

View File

@ -70,6 +70,7 @@ type Config struct {
SatelliteName string `help:"used to display at web satellite console" default:"Storj"`
SatelliteOperator string `help:"name of organization which set up satellite" default:"Storj Labs" `
TermsAndConditionsURL string `help:"url link to terms and conditions page" default:"https://storj.io/storage-sla/"`
SegmentIOPublicKey string `help:"used to initialize segment.io at web satellite console" default:""`
}
// Server represents console web server
@ -215,10 +216,11 @@ func (server *Server) appHandler(w http.ResponseWriter, r *http.Request) {
cspValues := []string{
"default-src 'self'",
"connect-src 'self' api.segment.io",
"frame-ancestors " + server.config.FrameAncestors,
"frame-src 'self' *.stripe.com",
"img-src 'self' data:",
"script-src 'self' *.stripe.com cdn.segment.com",
"img-src 'self' data: *.customer.io",
"script-src 'self' *.stripe.com cdn.segment.com *.customer.io",
}
header.Set(contentType, "text/html; charset=UTF-8")
@ -228,10 +230,12 @@ func (server *Server) appHandler(w http.ResponseWriter, r *http.Request) {
var data struct {
SatelliteName string
SegmentIOPublicKey string
StripePublicKey string
}
data.SatelliteName = server.config.SatelliteName
data.SegmentIOPublicKey = server.config.SegmentIOPublicKey
data.StripePublicKey = server.stripePublicKey
if server.templates.index == nil || server.templates.index.Execute(w, data) != nil {

View File

@ -61,6 +61,9 @@
# name of organization which set up satellite
# console.satellite-operator: Storj Labs
# used to initialize segment.io at web satellite console
# console.segment-io-public-key: ""
# used to communicate with web crawlers and other web robots
# console.seo: "User-agent: *\nDisallow: \nDisallow: /cgi-bin/"

View File

@ -4,6 +4,7 @@
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1, viewport-fit=cover">
<meta name="satellite-name" content="{{ .SatelliteName }}">
<meta name="segment-io" content="{{ .SegmentIOPublicKey }}">
<meta name="stripe-public-key" content="{{ .StripePublicKey }}">
<title>{{ .SatelliteName }}</title>
<link rel="shortcut icon" href="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAYAAABzenr0AAAACXBIWXMAABYlAAAWJQFJUiTwAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAL8SURBVHgBxVcxTFNRFL01JvylrRsmNWETWWSybg5I3NTQBCdRFyfrDuoKMgMyOQgdTcDAJmrUrWWCgQIbhJKy0TJQpsc73P/S9/tfP+8/GnqSn1fo77/3nnPufe8nhAR1ETeoy7hJjpj93/ycu0+UuUVuEA5Y2xaifirEVpX/nvknnBFbgpMGUfmIKOkRLRT578oxXy6IJcFCialH0EyaaPoZBy7tEQ3NEY1IKd4/iidHwqYLijLA559cuY6dT0RjBU5AAYm9fiivLFnBKMGBTyeqQ4BXhXDwdqjUiKZkskOzREsbzeeBNRMCEiDgr12uYl1WNbnW/oc2iUys8jrQyyxhHRkM3hdgAMFBHQyGG/GDqyDlsSeS/npQC99jlEBpOnyX2XCF8sGhZLbeMLMZkCDbJ1nYYTfDeMP9fMH5y5vmIKYE8RxUjBXPedDH1Zu6I9QFSzLQxErz4Xn5oNwg+2NSmuv3Lkvz4QlTi8rupDlBmA6tqQLrnYNCvoxSNAOtUEaakwzMv+ALidTP2OlKKiSK75Cs6hy9NYFkjzmG1SBCIuUq0Za8pgydge8R9E+e10qNrGE1ikH5435mo11bQgr4B9LEgVUC0Npm1o+vcuvBxB1NYFsaaeC2XUuW/Xs7msC9Xqa+MMa9jQr1KtXAQoKYHakeskbIhDrVasdTbbVY4s8ZYld/9PWuyeTSHksFBjBFcZ+aH/j/yZk5gcAcgImgIX6MNsKKhKBta1sB2A3HV5pD6iJQIzw/MICwoohc1F6ALBH03XemFYPl+VdzcBNUh6j5gZZEcP341opAAnX/AXl/A0FlrrshgMRR+YUvPPN8CHgAxlqWVYuEdH7V/ZilA6cosFDa53EcmUDKC+7X+IwxHEVhO0DK6aeXH88uHcWQA8xE7Yg69M6xgdWZUEFtNNDyx1s2KnyDIxu22zdZTjgWhANm/vL6clGIsnw3+Fbk94RreS8AMGrBxvwoT0lMPnSNC2JJoAPdgnMBJLjKq5lzAp1C19+OzwFiYzAU5f7eeQAAAABJRU5ErkJggg==" type="image/x-icon">

View File

@ -1070,6 +1070,11 @@
"integrity": "sha512-ce5d3q03Ex0sy4R14722Rmt6MT07Ua+k4FwDfdcToYJcMKNtRVQvJ6JCAPdAmAnbRb6CsX6aYb9m96NGod9uTw==",
"dev": true
},
"@types/segment-analytics": {
"version": "0.0.32",
"resolved": "https://registry.npmjs.org/@types/segment-analytics/-/segment-analytics-0.0.32.tgz",
"integrity": "sha512-p0SHnfHfZwemTeaISvu8WUXtw81A4AOU4GEr7B9S9jLx2iu/z/4aLT0flRJtHVusVAlMeJSdobn0uD/oR1sFEw=="
},
"@types/sinon": {
"version": "7.0.13",
"resolved": "https://registry.npmjs.org/@types/sinon/-/sinon-7.0.13.tgz",
@ -9627,8 +9632,7 @@
"load-script": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/load-script/-/load-script-1.0.0.tgz",
"integrity": "sha1-BJGTngvuVkPuSUp+PaPSuscMbKQ=",
"dev": true
"integrity": "sha1-BJGTngvuVkPuSUp+PaPSuscMbKQ="
},
"loader-runner": {
"version": "2.4.0",
@ -15805,15 +15809,6 @@
"resolved": "https://registry.npmjs.org/vue-router/-/vue-router-3.1.2.tgz",
"integrity": "sha512-WssQEHSEvIS1/CI4CO2T8LJdoK4Q9Ngox28K7FDNMTfzNTk2WS5D0dDlqYCaPG+AG4Z8wJkn1KrBc7AhspZJUQ=="
},
"vue-segment-analytics": {
"version": "0.3.2",
"resolved": "https://registry.npmjs.org/vue-segment-analytics/-/vue-segment-analytics-0.3.2.tgz",
"integrity": "sha512-jajq+K991iEv18QDBG4INWvHXH+Ur/IYJdfbQOOUYdDSP6j/UYSGwFfv6JTgRuEx1PO5jZEfSKHRbWSU7MId7A==",
"dev": true,
"requires": {
"load-script": "~1.0.0"
}
},
"vue-style-loader": {
"version": "4.1.2",
"resolved": "https://registry.npmjs.org/vue-style-loader/-/vue-style-loader-4.1.2.tgz",

View File

@ -10,6 +10,7 @@
"dev": "vue-cli-service build --mode development"
},
"dependencies": {
"@types/segment-analytics": "0.0.32",
"apollo-cache-inmemory": "1.6.3",
"apollo-client": "2.6.4",
"apollo-link": "1.2.12",
@ -17,6 +18,7 @@
"apollo-link-http": "1.5.15",
"graphql": "14.5.4",
"graphql-tag": "2.10.1",
"load-script": "^1.0.0",
"moment": "2.24.0",
"stripe": "7.8.0",
"vue": "2.6.10",
@ -38,24 +40,23 @@
"@vue/test-utils": "1.0.0-beta.29",
"babel-core": "7.0.0-bridge.0",
"compression-webpack-plugin": "3.0.0",
"stylelint": "11.1.1",
"stylelint-webpack-plugin": "1.0.2",
"stylelint-config-standard": "19.0.0",
"stylelint-scss": "3.12.0",
"jest-fetch-mock": "2.1.2",
"node-sass": "4.12.0",
"sass-loader": "7.1.0",
"sinon": "7.4.1",
"stylelint": "11.1.1",
"stylelint-config-standard": "19.0.0",
"stylelint-scss": "3.12.0",
"stylelint-webpack-plugin": "1.0.2",
"ts-jest": "24.0.2",
"tslint": "5.19.0",
"tslint-consistent-codestyle": "1.15.1",
"tslint-loader": "3.5.4",
"typescript": "3.5.3",
"vue-segment-analytics": "0.3.2",
"vue-svg-loader": "0.12.0",
"vue-template-compiler": "2.6.10",
"vue-tslint": "0.3.2",
"vue-tslint-loader": "3.5.6",
"vue-template-compiler": "2.6.10",
"webpack": "4.39.3"
},
"postcss": {

View File

@ -38,10 +38,15 @@ export default class App extends Vue {
public mounted(): void {
const satelliteName = MetaUtils.getMetaContent('satellite-name');
const segmentioId = MetaUtils.getMetaContent('segment-io');
if (satelliteName) {
this.$store.dispatch(APP_STATE_ACTIONS.SET_SATELLITE_NAME, satelliteName);
}
if (segmentioId) {
this.$segment.init(segmentioId);
}
}
public onClick(e: Event): void {

View File

@ -5,6 +5,7 @@ import Vue, { VNode } from 'vue';
import { DirectiveBinding } from 'vue/types/options';
import { NotificatorPlugin } from '@/utils/plugins/notificator';
import { SegmentioPlugin } from '@/utils/plugins/segment';
import App from './App.vue';
import { router } from './router';
@ -15,8 +16,10 @@ Vue.config.performance = true;
Vue.config.productionTip = false;
const notificator = new NotificatorPlugin();
const segment = new SegmentioPlugin();
Vue.use(notificator);
Vue.use(segment);
let clickOutsideEvent: EventListener;

View File

@ -4,10 +4,11 @@
import Vue from 'vue';
import { Notificator } from '@/utils/plugins/notificator';
import { Segmentio } from '@/utils/plugins/segment';
declare module 'vue/types/vue' {
interface Vue {
$segment: any; // define real typings here if you want
$segment: Segmentio; // define real typings here if you want
$notify: Notificator;
}
}

View File

@ -0,0 +1,8 @@
// Copyright (C) 2019 Storj Labs, Inc.
// See LICENSE for copying information.
export enum SegmentEvent {
CLICKED_LOGO = 'clicked-on-logo',
CLICKED_LOGIN = 'clicked-on-login',
CLICKED_BACK_TO_LOGIN = 'clicked-on-back-to-login',
}

View File

@ -0,0 +1,58 @@
// Copyright (C) 2019 Storj Labs, Inc.
// See LICENSE for copying information.
import loadScript from 'load-script';
import { SegmentEvent } from '@/utils/constants/analyticsEventNames';
/**
* Segmentio is a wrapper around segment.io analytics package
*/
export class Segmentio {
analytics: SegmentAnalytics.AnalyticsJS;
public init(key: string) {
if (this.analytics || key.length === 0 || key.includes('SegmentIOPublicKey')) {
return;
}
const source = `https://cdn.segment.com/analytics.js/v1/${key}/analytics.min.js`;
loadScript(source, (error) => {
if (error) {
return;
}
this.analytics = window['analytics'];
});
this.page();
}
public page() {
if (!this.analytics) {
return;
}
this.analytics.page();
}
public identify() {
if (!this.analytics) {
return;
}
this.analytics.identify();
}
public track(event: SegmentEvent, properties?: Object, options?: SegmentAnalytics.SegmentOpts, callback?: () => void) {
if (!this.analytics) {
return;
}
this.analytics.track(event, properties, options, callback);
}
}
export class SegmentioPlugin {
public install(Vue) {
Vue.prototype.$segment = new Segmentio();
}
}

View File

@ -15,7 +15,8 @@
"strictPropertyInitialization": false,
"types": [
"webpack-env",
"jest"
"jest",
"segment-analytics"
],
"paths": {
"@/*": [