[NEW] Workspace Manual Registration (#15442)
parent
376e37bfb6
commit
e6a61d17e2
@ -0,0 +1,30 @@ |
|||||||
|
import { check } from 'meteor/check'; |
||||||
|
|
||||||
|
import { API } from '../api'; |
||||||
|
import { hasRole } from '../../../authorization'; |
||||||
|
import { saveRegistrationData } from '../../../cloud/server/functions/saveRegistrationData'; |
||||||
|
import { retrieveRegistrationStatus } from '../../../cloud/server/functions/retrieveRegistrationStatus'; |
||||||
|
|
||||||
|
API.v1.addRoute('cloud.manualRegister', { authRequired: true }, { |
||||||
|
post() { |
||||||
|
check(this.bodyParams, { |
||||||
|
cloudBlob: String, |
||||||
|
}); |
||||||
|
|
||||||
|
if (!hasRole(this.userId, 'admin')) { |
||||||
|
return API.v1.unauthorized(); |
||||||
|
} |
||||||
|
|
||||||
|
const registrationInfo = retrieveRegistrationStatus(); |
||||||
|
|
||||||
|
if (registrationInfo.connectToCloud) { |
||||||
|
return API.v1.failure('Workspace is already registered'); |
||||||
|
} |
||||||
|
|
||||||
|
const settingsData = JSON.parse(Buffer.from(this.bodyParams.cloudBlob, 'base64').toString()); |
||||||
|
|
||||||
|
Promise.await(saveRegistrationData(settingsData)); |
||||||
|
|
||||||
|
return API.v1.success(); |
||||||
|
}, |
||||||
|
}); |
||||||
@ -0,0 +1,26 @@ |
|||||||
|
.rc-promtp { |
||||||
|
display: flex; |
||||||
|
|
||||||
|
min-height: 188px; |
||||||
|
padding: 1rem; |
||||||
|
|
||||||
|
border-radius: 2px; |
||||||
|
background: #2f343d; |
||||||
|
flex-flow: column wrap; |
||||||
|
justify-content: space-between; |
||||||
|
|
||||||
|
&--element, |
||||||
|
&--element[disabled] { |
||||||
|
flex: 1 1 auto; |
||||||
|
|
||||||
|
resize: none; |
||||||
|
|
||||||
|
color: #cbced1; |
||||||
|
border: none; |
||||||
|
background: none; |
||||||
|
|
||||||
|
font-family: Menlo, Monaco, Consolas, Liberation Mono, Courier New, monospace; |
||||||
|
font-size: 14px; |
||||||
|
line-height: 20px; |
||||||
|
} |
||||||
|
} |
||||||
@ -0,0 +1,36 @@ |
|||||||
|
<template name="cloudRegisterManually"> |
||||||
|
{{> header sectionName="Cloud_Register_manually" hideHelp=true fullpage=true}} |
||||||
|
{{# if copyStep }} |
||||||
|
<form class="preferences-page__content"> |
||||||
|
<p class="rc-modal__description">{{_ "Cloud_register_offline_helper" }}</p> |
||||||
|
<div class="rc-promtp"> |
||||||
|
<textarea class="rc-promtp--element" disabled>{{clientKey}}</textarea> |
||||||
|
<button class="rc-button rc-button--primary js-copy" data-clipboard-text="{{clientKey}}"> |
||||||
|
{{>icon icon='copy'}} {{_ "Copy"}} |
||||||
|
</button> |
||||||
|
</div> |
||||||
|
<p class="rc-modal__description js-cloud">{{#if cloudLink}} {{{cloudLink}}} {{else}} <a href="https://cloud.rocket.chat" rel="noopener noreferrer" class="cloud-console-btn" target="_blank"></a>{{/if}}</p> |
||||||
|
</form> |
||||||
|
|
||||||
|
<footer class="rc-modal__footer rc-modal__footer--empty"> |
||||||
|
<button class="rc-button rc-button--primary js-next">{{_ "Next"}}</button> |
||||||
|
</footer> |
||||||
|
|
||||||
|
{{else}} |
||||||
|
|
||||||
|
<form class="preferences-page__content"> |
||||||
|
<p class="rc-modal__description">{{_ "Cloud_register_offline_finish_helper"}}</p> |
||||||
|
<div class="rc-promtp"> |
||||||
|
<textarea class="js-cloud-key rc-promtp--element" placeholder="{{_ "Paste_here"}}" disabled={{isLoading}}></textarea> |
||||||
|
</div> |
||||||
|
</form> |
||||||
|
|
||||||
|
<footer class="rc-modal__footer rc-modal__footer--empty"> |
||||||
|
<button class="rc-button rc-button--secondary js-back">{{_ "Back"}}</button> |
||||||
|
<button class="rc-button rc-button--primary js-finish" disabled='{{disabled}}'> |
||||||
|
{{#if isLoading}} {{> loading}} {{/if}} |
||||||
|
<span style="{{#if isLoading}} visibility:hidden {{/if}}">{{_ "Finish Registration"}}</span> |
||||||
|
</button> |
||||||
|
</footer> |
||||||
|
{{/if}} |
||||||
|
</template> |
||||||
@ -0,0 +1,106 @@ |
|||||||
|
import { Meteor } from 'meteor/meteor'; |
||||||
|
import { ReactiveDict } from 'meteor/reactive-dict'; |
||||||
|
import { ReactiveVar } from 'meteor/reactive-var'; |
||||||
|
import { Template } from 'meteor/templating'; |
||||||
|
import { TAPi18n } from 'meteor/rocketchat:tap-i18n'; |
||||||
|
import Clipboard from 'clipboard'; |
||||||
|
import toastr from 'toastr'; |
||||||
|
|
||||||
|
import { APIClient } from '../../../utils/client'; |
||||||
|
import { modal } from '../../../ui-utils/client'; |
||||||
|
|
||||||
|
import './cloudRegisterManually.html'; |
||||||
|
import './cloudRegisterManually.css'; |
||||||
|
|
||||||
|
const CLOUD_STEPS = { |
||||||
|
COPY: 0, |
||||||
|
PASTE: 1, |
||||||
|
DONE: 2, |
||||||
|
ERROR: 3, |
||||||
|
}; |
||||||
|
|
||||||
|
Template.cloudRegisterManually.events({ |
||||||
|
'submit form'(e) { |
||||||
|
e.preventDefault(); |
||||||
|
}, |
||||||
|
'input .js-cloud-key'(e, instance) { |
||||||
|
instance.state.set('cloudKey', e.currentTarget.value); |
||||||
|
}, |
||||||
|
'click .js-next'(event, instance) { |
||||||
|
instance.state.set('step', CLOUD_STEPS.PASTE); |
||||||
|
}, |
||||||
|
'click .js-back'(event, instance) { |
||||||
|
instance.state.set('step', CLOUD_STEPS.COPY); |
||||||
|
}, |
||||||
|
'click .js-finish'(event, instance) { |
||||||
|
instance.state.set('loading', true); |
||||||
|
|
||||||
|
APIClient |
||||||
|
.post('v1/cloud.manualRegister', {}, { cloudBlob: instance.state.get('cloudKey') }) |
||||||
|
.then(() => modal.open({ |
||||||
|
type: 'success', |
||||||
|
title: TAPi18n.__('Success'), |
||||||
|
text: TAPi18n.__('Cloud_register_success'), |
||||||
|
confirmButtonText: TAPi18n.__('Ok'), |
||||||
|
closeOnConfirm: false, |
||||||
|
showCancelButton: false, |
||||||
|
}, () => window.location.reload())) |
||||||
|
.catch(() => modal.open({ |
||||||
|
type: 'error', |
||||||
|
title: TAPi18n.__('Error'), |
||||||
|
text: TAPi18n.__('Cloud_register_error'), |
||||||
|
})) |
||||||
|
.then(() => instance.state.set('loading', false)); |
||||||
|
}, |
||||||
|
}); |
||||||
|
|
||||||
|
Template.cloudRegisterManually.helpers({ |
||||||
|
cloudLink() { |
||||||
|
return Template.instance().cloudLink.get(); |
||||||
|
}, |
||||||
|
copyStep() { |
||||||
|
return Template.instance().state.get('step') === CLOUD_STEPS.COPY; |
||||||
|
}, |
||||||
|
clientKey() { |
||||||
|
return Template.instance().state.get('clientKey'); |
||||||
|
}, |
||||||
|
isLoading() { |
||||||
|
return Template.instance().state.get('loading'); |
||||||
|
}, |
||||||
|
step() { |
||||||
|
return Template.instance().state.get('step'); |
||||||
|
}, |
||||||
|
disabled() { |
||||||
|
const { state } = Template.instance(); |
||||||
|
|
||||||
|
const shouldDisable = state.get('cloudKey').trim().length === 0 || state.get('loading'); |
||||||
|
|
||||||
|
return shouldDisable && 'disabled'; |
||||||
|
}, |
||||||
|
}); |
||||||
|
|
||||||
|
Template.cloudRegisterManually.onRendered(function() { |
||||||
|
const clipboard = new Clipboard('.js-copy'); |
||||||
|
clipboard.on('success', function() { |
||||||
|
toastr.success(TAPi18n.__('Copied')); |
||||||
|
}); |
||||||
|
|
||||||
|
const btn = this.find('.cloud-console-btn'); |
||||||
|
// After_copy_the_text_go_to_cloud
|
||||||
|
this.cloudLink.set(TAPi18n.__('Cloud_click_here').replace(/(\[(.*)\]\(\))/ig, (_, __, text) => btn.outerHTML.replace('</a>', `${ text }</a>`))); |
||||||
|
}); |
||||||
|
|
||||||
|
Template.cloudRegisterManually.onCreated(function() { |
||||||
|
this.cloudLink = new ReactiveVar(); |
||||||
|
this.state = new ReactiveDict({ |
||||||
|
step: CLOUD_STEPS.COPY, |
||||||
|
loading: false, |
||||||
|
clientKey: '', |
||||||
|
cloudKey: '', |
||||||
|
error: '', |
||||||
|
}); |
||||||
|
|
||||||
|
Meteor.call('cloud:getWorkspaceRegisterData', (error, result) => { |
||||||
|
this.state.set('clientKey', result); |
||||||
|
}); |
||||||
|
}); |
||||||
@ -0,0 +1,54 @@ |
|||||||
|
import { settings } from '../../../settings'; |
||||||
|
import { Users } from '../../../models'; |
||||||
|
import { statistics } from '../../../statistics'; |
||||||
|
|
||||||
|
export function buildWorkspaceRegistrationData() { |
||||||
|
const stats = statistics.get(); |
||||||
|
|
||||||
|
const address = settings.get('Site_Url'); |
||||||
|
const siteName = settings.get('Site_Name'); |
||||||
|
|
||||||
|
// If we have it lets send it because likely an update
|
||||||
|
const workspaceId = settings.get('Cloud_Workspace_Id'); |
||||||
|
|
||||||
|
const firstUser = Users.getOldest({ name: 1, emails: 1 }); |
||||||
|
const contactName = firstUser && firstUser.name; |
||||||
|
let contactEmail = firstUser && firstUser.emails && firstUser.emails[0].address; |
||||||
|
|
||||||
|
if (settings.get('Organization_Email')) { |
||||||
|
contactEmail = settings.get('Organization_Email'); |
||||||
|
} |
||||||
|
|
||||||
|
const allowMarketing = settings.get('Allow_Marketing_Emails'); |
||||||
|
|
||||||
|
const accountName = settings.get('Organization_Name'); |
||||||
|
|
||||||
|
const website = settings.get('Website'); |
||||||
|
|
||||||
|
const agreePrivacyTerms = settings.get('Cloud_Service_Agree_PrivacyTerms'); |
||||||
|
|
||||||
|
const { organizationType, industry, size: orgSize, country, language, serverType: workspaceType } = stats.wizard; |
||||||
|
|
||||||
|
return { |
||||||
|
uniqueId: stats.uniqueId, |
||||||
|
workspaceId, |
||||||
|
address, |
||||||
|
contactName, |
||||||
|
contactEmail, |
||||||
|
allowMarketing, |
||||||
|
accountName, |
||||||
|
organizationType, |
||||||
|
industry, |
||||||
|
orgSize, |
||||||
|
country, |
||||||
|
language, |
||||||
|
agreePrivacyTerms, |
||||||
|
website, |
||||||
|
siteName, |
||||||
|
workspaceType, |
||||||
|
deploymentMethod: stats.deploy.method, |
||||||
|
deploymentPlatform: stats.deploy.platform, |
||||||
|
version: stats.version, |
||||||
|
setupComplete: true, |
||||||
|
}; |
||||||
|
} |
||||||
@ -0,0 +1,22 @@ |
|||||||
|
import { Settings } from '../../../models/server/raw'; |
||||||
|
|
||||||
|
export function saveRegistrationData({ |
||||||
|
workspaceId, |
||||||
|
client_name, |
||||||
|
client_id, |
||||||
|
client_secret, |
||||||
|
client_secret_expires_at, |
||||||
|
publicKey, |
||||||
|
registration_client_uri, |
||||||
|
}) { |
||||||
|
return Promise.all([ |
||||||
|
Settings.updateValueById('Register_Server', true), |
||||||
|
Settings.updateValueById('Cloud_Workspace_Id', workspaceId), |
||||||
|
Settings.updateValueById('Cloud_Workspace_Name', client_name), |
||||||
|
Settings.updateValueById('Cloud_Workspace_Client_Id', client_id), |
||||||
|
Settings.updateValueById('Cloud_Workspace_Client_Secret', client_secret), |
||||||
|
Settings.updateValueById('Cloud_Workspace_Client_Secret_Expires_At', client_secret_expires_at), |
||||||
|
Settings.updateValueById('Cloud_Workspace_PublicKey', publicKey), |
||||||
|
Settings.updateValueById('Cloud_Workspace_Registration_Client_Uri', registration_client_uri), |
||||||
|
]); |
||||||
|
} |
||||||
File diff suppressed because it is too large
Load Diff
Loading…
Reference in new issue