[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