diff --git a/packages/rocketchat-oauth2-server-config/admin/client/collection.coffee b/packages/rocketchat-oauth2-server-config/admin/client/collection.coffee deleted file mode 100644 index a0f53700c27c..000000000000 --- a/packages/rocketchat-oauth2-server-config/admin/client/collection.coffee +++ /dev/null @@ -1 +0,0 @@ -@ChatOAuthApps = new Mongo.Collection 'rocketchat_oauth_apps' diff --git a/packages/rocketchat-oauth2-server-config/admin/client/collection.js b/packages/rocketchat-oauth2-server-config/admin/client/collection.js new file mode 100644 index 000000000000..f196d7dc17eb --- /dev/null +++ b/packages/rocketchat-oauth2-server-config/admin/client/collection.js @@ -0,0 +1 @@ +this.ChatOAuthApps = new Mongo.Collection('rocketchat_oauth_apps'); diff --git a/packages/rocketchat-oauth2-server-config/admin/client/route.coffee b/packages/rocketchat-oauth2-server-config/admin/client/route.coffee deleted file mode 100644 index f2fcc3b83659..000000000000 --- a/packages/rocketchat-oauth2-server-config/admin/client/route.coffee +++ /dev/null @@ -1,17 +0,0 @@ -FlowRouter.route '/admin/oauth-apps', - name: 'admin-oauth-apps' - action: (params) -> - BlazeLayout.render 'main', - center: 'pageSettingsContainer' - pageTitle: t('OAuth_Applications') - pageTemplate: 'oauthApps' - - -FlowRouter.route '/admin/oauth-app/:id?', - name: 'admin-oauth-app' - action: (params) -> - BlazeLayout.render 'main', - center: 'pageSettingsContainer' - pageTitle: t('OAuth_Application') - pageTemplate: 'oauthApp' - params: params diff --git a/packages/rocketchat-oauth2-server-config/admin/client/route.js b/packages/rocketchat-oauth2-server-config/admin/client/route.js new file mode 100644 index 000000000000..7b0b7f469f2c --- /dev/null +++ b/packages/rocketchat-oauth2-server-config/admin/client/route.js @@ -0,0 +1,22 @@ +FlowRouter.route('/admin/oauth-apps', { + name: 'admin-oauth-apps', + action() { + return BlazeLayout.render('main', { + center: 'pageSettingsContainer', + pageTitle: t('OAuth_Applications'), + pageTemplate: 'oauthApps' + }); + } +}); + +FlowRouter.route('/admin/oauth-app/:id?', { + name: 'admin-oauth-app', + action(params) { + return BlazeLayout.render('main', { + center: 'pageSettingsContainer', + pageTitle: t('OAuth_Application'), + pageTemplate: 'oauthApp', + params + }); + } +}); diff --git a/packages/rocketchat-oauth2-server-config/admin/client/startup.coffee b/packages/rocketchat-oauth2-server-config/admin/client/startup.coffee deleted file mode 100644 index 0e4c45616177..000000000000 --- a/packages/rocketchat-oauth2-server-config/admin/client/startup.coffee +++ /dev/null @@ -1,5 +0,0 @@ -RocketChat.AdminBox.addOption - href: 'admin-oauth-apps' - i18nLabel: 'OAuth Apps' - permissionGranted: -> - return RocketChat.authz.hasAllPermission('manage-oauth-apps') diff --git a/packages/rocketchat-oauth2-server-config/admin/client/startup.js b/packages/rocketchat-oauth2-server-config/admin/client/startup.js new file mode 100644 index 000000000000..27cee4bd5597 --- /dev/null +++ b/packages/rocketchat-oauth2-server-config/admin/client/startup.js @@ -0,0 +1,7 @@ +RocketChat.AdminBox.addOption({ + href: 'admin-oauth-apps', + i18nLabel: 'OAuth Apps', + permissionGranted() { + return RocketChat.authz.hasAllPermission('manage-oauth-apps'); + } +}); diff --git a/packages/rocketchat-oauth2-server-config/admin/client/views/oauthApp.coffee b/packages/rocketchat-oauth2-server-config/admin/client/views/oauthApp.coffee deleted file mode 100644 index f8da9f6ce692..000000000000 --- a/packages/rocketchat-oauth2-server-config/admin/client/views/oauthApp.coffee +++ /dev/null @@ -1,81 +0,0 @@ -import toastr from 'toastr' -Template.oauthApp.onCreated -> - @subscribe 'oauthApps' - @record = new ReactiveVar - active: true - - -Template.oauthApp.helpers - hasPermission: -> - return RocketChat.authz.hasAllPermission 'manage-oauth-apps' - - data: -> - params = Template.instance().data.params?() - - if params?.id? - data = ChatOAuthApps.findOne({_id: params.id}) - if data? - data.authorization_url = Meteor.absoluteUrl("oauth/authorize") - data.access_token_url = Meteor.absoluteUrl("oauth/token") - - Template.instance().record.set data - return data - - return Template.instance().record.curValue - - -Template.oauthApp.events - "click .submit > .delete": -> - params = Template.instance().data.params() - - swal - title: t('Are_you_sure') - text: t('You_will_not_be_able_to_recover') - type: 'warning' - showCancelButton: true - confirmButtonColor: '#DD6B55' - confirmButtonText: t('Yes_delete_it') - cancelButtonText: t('Cancel') - closeOnConfirm: false - html: false - , -> - Meteor.call "deleteOAuthApp", params.id, (err, data) -> - swal - title: t('Deleted') - text: t('Your_entry_has_been_deleted') - type: 'success' - timer: 1000 - showConfirmButton: false - - FlowRouter.go "admin-oauth-apps" - - "click .submit > .save": -> - name = $('[name=name]').val().trim() - active = $('[name=active]:checked').val().trim() is "1" - redirectUri = $('[name=redirectUri]').val().trim() - - if name is '' - return toastr.error TAPi18n.__("The_application_name_is_required") - - if redirectUri is '' - return toastr.error TAPi18n.__("The_redirectUri_is_required") - - app = - name: name - active: active - redirectUri: redirectUri - - params = Template.instance().data.params?() - if params?.id? - Meteor.call "updateOAuthApp", params.id, app, (err, data) -> - if err? - return handleError(err) - - toastr.success TAPi18n.__("Application_updated") - else - Meteor.call "addOAuthApp", app, (err, data) -> - if err? - return handleError(err) - - toastr.success TAPi18n.__("Application_added") - FlowRouter.go "admin-oauth-app", {id: data._id} diff --git a/packages/rocketchat-oauth2-server-config/admin/client/views/oauthApp.js b/packages/rocketchat-oauth2-server-config/admin/client/views/oauthApp.js new file mode 100644 index 000000000000..0bf2d9e0e52b --- /dev/null +++ b/packages/rocketchat-oauth2-server-config/admin/client/views/oauthApp.js @@ -0,0 +1,94 @@ +/* globals ChatOAuthApps */ +import toastr from 'toastr'; + +Template.oauthApp.onCreated(function() { + this.subscribe('oauthApps'); + this.record = new ReactiveVar({ + active: true + }); +}); + +Template.oauthApp.helpers({ + hasPermission() { + return RocketChat.authz.hasAllPermission('manage-oauth-apps'); + }, + data() { + const instance = Template.instance(); + if (typeof instance.data.params === 'function') { + const params = instance.data.params(); + if (params && params.id) { + const data = ChatOAuthApps.findOne({ _id: params.id }); + if (data) { + data.authorization_url = Meteor.absoluteUrl('oauth/authorize'); + data.access_token_url = Meteor.absoluteUrl('oauth/token'); + Template.instance().record.set(data); + return data; + } + } + } + return Template.instance().record.curValue; + } +}); + +Template.oauthApp.events({ + 'click .submit > .delete'() { + const params = Template.instance().data.params(); + swal({ + title: t('Are_you_sure'), + text: t('You_will_not_be_able_to_recover'), + type: 'warning', + showCancelButton: true, + confirmButtonColor: '#DD6B55', + confirmButtonText: t('Yes_delete_it'), + cancelButtonText: t('Cancel'), + closeOnConfirm: false, + html: false + }, function() { + Meteor.call('deleteOAuthApp', params.id, function() { + swal({ + title: t('Deleted'), + text: t('Your_entry_has_been_deleted'), + type: 'success', + timer: 1000, + showConfirmButton: false + }); + FlowRouter.go('admin-oauth-apps'); + }); + }); + }, + 'click .submit > .save'() { + const instance = Template.instance(); + const name = $('[name=name]').val().trim(); + const active = $('[name=active]:checked').val().trim() === '1'; + const redirectUri = $('[name=redirectUri]').val().trim(); + if (name === '') { + return toastr.error(TAPi18n.__('The_application_name_is_required')); + } + if (redirectUri === '') { + return toastr.error(TAPi18n.__('The_redirectUri_is_required')); + } + const app = { + name, + active, + redirectUri + }; + if (typeof instance.data.params === 'function') { + const params = instance.data.params(); + if (params && params.id) { + return Meteor.call('updateOAuthApp', params.id, app, function(err) { + if (err != null) { + return handleError(err); + } + toastr.success(TAPi18n.__('Application_updated')); + }); + } + } + Meteor.call('addOAuthApp', app, function(err, data) { + if (err != null) { + return handleError(err); + } + toastr.success(TAPi18n.__('Application_added')); + FlowRouter.go('admin-oauth-app', { id: data._id }); + }); + } +}); diff --git a/packages/rocketchat-oauth2-server-config/admin/client/views/oauthApps.coffee b/packages/rocketchat-oauth2-server-config/admin/client/views/oauthApps.coffee deleted file mode 100644 index 37e3df9d3ca0..000000000000 --- a/packages/rocketchat-oauth2-server-config/admin/client/views/oauthApps.coffee +++ /dev/null @@ -1,14 +0,0 @@ -import moment from 'moment' - -Template.oauthApps.onCreated -> - @subscribe 'oauthApps' - -Template.oauthApps.helpers - hasPermission: -> - return RocketChat.authz.hasAllPermission 'manage-oauth-apps' - - applications: -> - return ChatOAuthApps.find() - - dateFormated: (date) -> - return moment(date).format('L LT') diff --git a/packages/rocketchat-oauth2-server-config/admin/client/views/oauthApps.js b/packages/rocketchat-oauth2-server-config/admin/client/views/oauthApps.js new file mode 100644 index 000000000000..00b72fa4fe3e --- /dev/null +++ b/packages/rocketchat-oauth2-server-config/admin/client/views/oauthApps.js @@ -0,0 +1,16 @@ +/* globals ChatOAuthApps */ +import moment from 'moment'; + +Template.oauthApps.onCreated(() => this.subscribe('oauthApps')); + +Template.oauthApps.helpers({ + hasPermission() { + return RocketChat.authz.hasAllPermission('manage-oauth-apps'); + }, + applications() { + return ChatOAuthApps.find(); + }, + dateFormated(date) { + return moment(date).format('L LT'); + } +}); diff --git a/packages/rocketchat-oauth2-server-config/admin/server/methods/addOAuthApp.coffee b/packages/rocketchat-oauth2-server-config/admin/server/methods/addOAuthApp.coffee deleted file mode 100644 index fca6a47f1c28..000000000000 --- a/packages/rocketchat-oauth2-server-config/admin/server/methods/addOAuthApp.coffee +++ /dev/null @@ -1,22 +0,0 @@ -Meteor.methods - addOAuthApp: (application) -> - if not RocketChat.authz.hasPermission @userId, 'manage-oauth-apps' - throw new Meteor.Error 'error-not-allowed', 'Not allowed', { method: 'addOAuthApp' } - - if not _.isString(application.name) or application.name.trim() is '' - throw new Meteor.Error 'error-invalid-name', 'Invalid name', { method: 'addOAuthApp' } - - if not _.isString(application.redirectUri) or application.redirectUri.trim() is '' - throw new Meteor.Error 'error-invalid-redirectUri', 'Invalid redirectUri', { method: 'addOAuthApp' } - - if not _.isBoolean(application.active) - throw new Meteor.Error 'error-invalid-arguments', 'Invalid arguments', { method: 'addOAuthApp' } - - application.clientId = Random.id() - application.clientSecret = Random.secret() - application._createdAt = new Date - application._createdBy = RocketChat.models.Users.findOne @userId, {fields: {username: 1}} - - application._id = RocketChat.models.OAuthApps.insert application - - return application diff --git a/packages/rocketchat-oauth2-server-config/admin/server/methods/addOAuthApp.js b/packages/rocketchat-oauth2-server-config/admin/server/methods/addOAuthApp.js new file mode 100644 index 000000000000..80ddecef58fc --- /dev/null +++ b/packages/rocketchat-oauth2-server-config/admin/server/methods/addOAuthApp.js @@ -0,0 +1,22 @@ +Meteor.methods({ + addOAuthApp(application) { + if (!RocketChat.authz.hasPermission(this.userId, 'manage-oauth-apps')) { + throw new Meteor.Error('error-not-allowed', 'Not allowed', { method: 'addOAuthApp' }); + } + if (!_.isString(application.name) || application.name.trim() === '') { + throw new Meteor.Error('error-invalid-name', 'Invalid name', { method: 'addOAuthApp' }); + } + if (!_.isString(application.redirectUri) || application.redirectUri.trim() === '') { + throw new Meteor.Error('error-invalid-redirectUri', 'Invalid redirectUri', { method: 'addOAuthApp' }); + } + if (!_.isBoolean(application.active)) { + throw new Meteor.Error('error-invalid-arguments', 'Invalid arguments', { method: 'addOAuthApp' }); + } + application.clientId = Random.id(); + application.clientSecret = Random.secret(); + application._createdAt = new Date; + application._createdBy = RocketChat.models.Users.findOne(this.userId, { fields: { username: 1 } }); + application._id = RocketChat.models.OAuthApps.insert(application); + return application; + } +}); diff --git a/packages/rocketchat-oauth2-server-config/admin/server/methods/deleteOAuthApp.coffee b/packages/rocketchat-oauth2-server-config/admin/server/methods/deleteOAuthApp.coffee deleted file mode 100644 index f0367d88ca42..000000000000 --- a/packages/rocketchat-oauth2-server-config/admin/server/methods/deleteOAuthApp.coffee +++ /dev/null @@ -1,14 +0,0 @@ -Meteor.methods - deleteOAuthApp: (applicationId) -> - if not RocketChat.authz.hasPermission @userId, 'manage-oauth-apps' - throw new Meteor.Error('error-not-allowed', 'Not allowed', { method: 'deleteOAuthApp' }); - - application = RocketChat.models.OAuthApps.findOne(applicationId) - - if not application? - throw new Meteor.Error('error-application-not-found', 'Application not found', { method: 'deleteOAuthApp' }); - - - RocketChat.models.OAuthApps.remove _id: applicationId - - return true diff --git a/packages/rocketchat-oauth2-server-config/admin/server/methods/deleteOAuthApp.js b/packages/rocketchat-oauth2-server-config/admin/server/methods/deleteOAuthApp.js new file mode 100644 index 000000000000..1426496ed407 --- /dev/null +++ b/packages/rocketchat-oauth2-server-config/admin/server/methods/deleteOAuthApp.js @@ -0,0 +1,13 @@ +Meteor.methods({ + deleteOAuthApp(applicationId) { + if (!RocketChat.authz.hasPermission(this.userId, 'manage-oauth-apps')) { + throw new Meteor.Error('error-not-allowed', 'Not allowed', { method: 'deleteOAuthApp' }); + } + const application = RocketChat.models.OAuthApps.findOne(applicationId); + if (application == null) { + throw new Meteor.Error('error-application-not-found', 'Application not found', { method: 'deleteOAuthApp' }); + } + RocketChat.models.OAuthApps.remove({ _id: applicationId }); + return true; + } +}); diff --git a/packages/rocketchat-oauth2-server-config/admin/server/methods/updateOAuthApp.coffee b/packages/rocketchat-oauth2-server-config/admin/server/methods/updateOAuthApp.coffee deleted file mode 100644 index ea9dba6cdca9..000000000000 --- a/packages/rocketchat-oauth2-server-config/admin/server/methods/updateOAuthApp.coffee +++ /dev/null @@ -1,27 +0,0 @@ -Meteor.methods - updateOAuthApp: (applicationId, application) -> - if not RocketChat.authz.hasPermission @userId, 'manage-oauth-apps' - throw new Meteor.Error 'error-not-allowed', 'Not allowed', { method: 'updateOAuthApp' } - - if not _.isString(application.name) or application.name.trim() is '' - throw new Meteor.Error 'error-invalid-name', 'Invalid name', { method: 'updateOAuthApp' } - - if not _.isString(application.redirectUri) or application.redirectUri.trim() is '' - throw new Meteor.Error 'error-invalid-redirectUri', 'Invalid redirectUri', { method: 'updateOAuthApp' } - - if not _.isBoolean(application.active) - throw new Meteor.Error 'error-invalid-arguments', 'Invalid arguments', { method: 'updateOAuthApp' } - - currentApplication = RocketChat.models.OAuthApps.findOne(applicationId) - if not currentApplication? - throw new Meteor.Error 'error-application-not-found', 'Application not found', { method: 'updateOAuthApp' } - - RocketChat.models.OAuthApps.update applicationId, - $set: - name: application.name - active: application.active - redirectUri: application.redirectUri - _updatedAt: new Date - _updatedBy: RocketChat.models.Users.findOne @userId, {fields: {username: 1}} - - return RocketChat.models.OAuthApps.findOne(applicationId) diff --git a/packages/rocketchat-oauth2-server-config/admin/server/methods/updateOAuthApp.js b/packages/rocketchat-oauth2-server-config/admin/server/methods/updateOAuthApp.js new file mode 100644 index 000000000000..78a742b726f0 --- /dev/null +++ b/packages/rocketchat-oauth2-server-config/admin/server/methods/updateOAuthApp.js @@ -0,0 +1,34 @@ +Meteor.methods({ + updateOAuthApp(applicationId, application) { + if (!RocketChat.authz.hasPermission(this.userId, 'manage-oauth-apps')) { + throw new Meteor.Error('error-not-allowed', 'Not allowed', { method: 'updateOAuthApp' }); + } + if (!_.isString(application.name) || application.name.trim() === '') { + throw new Meteor.Error('error-invalid-name', 'Invalid name', { method: 'updateOAuthApp' }); + } + if (!_.isString(application.redirectUri) || application.redirectUri.trim() === '') { + throw new Meteor.Error('error-invalid-redirectUri', 'Invalid redirectUri', { method: 'updateOAuthApp' }); + } + if (!_.isBoolean(application.active)) { + throw new Meteor.Error('error-invalid-arguments', 'Invalid arguments', { method: 'updateOAuthApp' }); + } + const currentApplication = RocketChat.models.OAuthApps.findOne(applicationId); + if (currentApplication == null) { + throw new Meteor.Error('error-application-not-found', 'Application not found', { method: 'updateOAuthApp' }); + } + RocketChat.models.OAuthApps.update(applicationId, { + $set: { + name: application.name, + active: application.active, + redirectUri: application.redirectUri, + _updatedAt: new Date, + _updatedBy: RocketChat.models.Users.findOne(this.userId, { + fields: { + username: 1 + } + }) + } + }); + return RocketChat.models.OAuthApps.findOne(applicationId); + } +}); diff --git a/packages/rocketchat-oauth2-server-config/admin/server/publications/oauthApps.coffee b/packages/rocketchat-oauth2-server-config/admin/server/publications/oauthApps.coffee deleted file mode 100644 index ef3d48a4f49c..000000000000 --- a/packages/rocketchat-oauth2-server-config/admin/server/publications/oauthApps.coffee +++ /dev/null @@ -1,8 +0,0 @@ -Meteor.publish 'oauthApps', -> - unless @userId - return @ready() - - if not RocketChat.authz.hasPermission @userId, 'manage-oauth-apps' - @error Meteor.Error "error-not-allowed", "Not allowed", { publish: 'oauthApps' } - - return RocketChat.models.OAuthApps.find() diff --git a/packages/rocketchat-oauth2-server-config/admin/server/publications/oauthApps.js b/packages/rocketchat-oauth2-server-config/admin/server/publications/oauthApps.js new file mode 100644 index 000000000000..33cc5f5ff955 --- /dev/null +++ b/packages/rocketchat-oauth2-server-config/admin/server/publications/oauthApps.js @@ -0,0 +1,9 @@ +Meteor.publish('oauthApps', function() { + if (!this.userId) { + return this.ready(); + } + if (!RocketChat.authz.hasPermission(this.userId, 'manage-oauth-apps')) { + this.error(Meteor.Error('error-not-allowed', 'Not allowed', { publish: 'oauthApps' })); + } + return RocketChat.models.OAuthApps.find(); +}); diff --git a/packages/rocketchat-oauth2-server-config/oauth/client/oauth2-client.coffee b/packages/rocketchat-oauth2-server-config/oauth/client/oauth2-client.coffee deleted file mode 100644 index 52c098f3b407..000000000000 --- a/packages/rocketchat-oauth2-server-config/oauth/client/oauth2-client.coffee +++ /dev/null @@ -1,47 +0,0 @@ -# @ChatOAuthApps = new Mongo.Collection 'rocketchat_oauth_apps' - -FlowRouter.route '/oauth/authorize', - action: (params, queryParams) -> - BlazeLayout.render 'main', - center: 'authorize' - modal: true - client_id: queryParams.client_id - redirect_uri: queryParams.redirect_uri - response_type: queryParams.response_type - state: queryParams.state - - -FlowRouter.route '/oauth/error/:error', - action: (params, queryParams) -> - BlazeLayout.render 'main', - center: 'oauth404' - modal: true - error: params.error - - -Template.authorize.onCreated -> - @subscribe 'authorizedOAuth' - @subscribe 'oauthClient', @data.client_id() - - -Template.authorize.helpers - getToken: -> - return localStorage.getItem('Meteor.loginToken') - - getClient: -> - return ChatOAuthApps.findOne() - - -Template.authorize.events - 'click #logout-oauth': -> - return Meteor.logout() - - 'click #cancel-oauth': -> - return window.close() - - -Template.authorize.onRendered -> - @autorun (c) => - if Meteor.user()?.oauth?.authorizedClients?.indexOf(@data.client_id()) > -1 - c.stop() - $('button[type=submit]').click() diff --git a/packages/rocketchat-oauth2-server-config/oauth/client/oauth2-client.js b/packages/rocketchat-oauth2-server-config/oauth/client/oauth2-client.js new file mode 100644 index 000000000000..afdc2a3cd879 --- /dev/null +++ b/packages/rocketchat-oauth2-server-config/oauth/client/oauth2-client.js @@ -0,0 +1,57 @@ +// @ChatOAuthApps = new Mongo.Collection 'rocketchat_oauth_apps' +/*globals ChatOAuthApps */ +FlowRouter.route('/oauth/authorize', { + action(params, queryParams) { + BlazeLayout.render('main', { + center: 'authorize', + modal: true, + client_id: queryParams.client_id, + redirect_uri: queryParams.redirect_uri, + response_type: queryParams.response_type, + state: queryParams.state + }); + } +}); + +FlowRouter.route('/oauth/error/:error', { + action(params) { + BlazeLayout.render('main', { + center: 'oauth404', + modal: true, + error: params.error + }); + } +}); + +Template.authorize.onCreated(function() { + this.subscribe('authorizedOAuth'); + this.subscribe('oauthClient', this.data.client_id()); +}); + +Template.authorize.helpers({ + getToken() { + return localStorage.getItem('Meteor.loginToken'); + }, + getClient() { + return ChatOAuthApps.findOne(); + } +}); + +Template.authorize.events({ + 'click #logout-oauth'() { + return Meteor.logout(); + }, + 'click #cancel-oauth'() { + return window.close(); + } +}); + +Template.authorize.onRendered(function() { + this.autorun(c => { + const user = Meteor.user(); + if (user && user.oauth && user.oauth.authorizedClients && user.oauth.authorizedClients.includes(this.data.client_id())) { + c.stop(); + $('button[type=submit]').click(); + } + }); +}); diff --git a/packages/rocketchat-oauth2-server-config/oauth/server/default-services.coffee b/packages/rocketchat-oauth2-server-config/oauth/server/default-services.coffee deleted file mode 100644 index fa457c95e66d..000000000000 --- a/packages/rocketchat-oauth2-server-config/oauth/server/default-services.coffee +++ /dev/null @@ -1,12 +0,0 @@ -if not RocketChat.models.OAuthApps.findOne('zapier') - RocketChat.models.OAuthApps.insert - _id: 'zapier' - name: 'Zapier' - active: true - clientId: 'zapier' - clientSecret: 'RTK6TlndaCIolhQhZ7_KHIGOKj41RnlaOq_o-7JKwLr' - redirectUri: 'https://zapier.com/dashboard/auth/oauth/return/App32270API/' - _createdAt: new Date - _createdBy: - _id: 'system' - username: 'system' diff --git a/packages/rocketchat-oauth2-server-config/oauth/server/default-services.js b/packages/rocketchat-oauth2-server-config/oauth/server/default-services.js new file mode 100644 index 000000000000..2a5ab569110e --- /dev/null +++ b/packages/rocketchat-oauth2-server-config/oauth/server/default-services.js @@ -0,0 +1,15 @@ +if (!RocketChat.models.OAuthApps.findOne('zapier')) { + RocketChat.models.OAuthApps.insert({ + _id: 'zapier', + name: 'Zapier', + active: true, + clientId: 'zapier', + clientSecret: 'RTK6TlndaCIolhQhZ7_KHIGOKj41RnlaOq_o-7JKwLr', + redirectUri: 'https://zapier.com/dashboard/auth/oauth/return/App32270API/', + _createdAt: new Date, + _createdBy: { + _id: 'system', + username: 'system' + } + }); +} diff --git a/packages/rocketchat-oauth2-server-config/oauth/server/oauth2-server.coffee b/packages/rocketchat-oauth2-server-config/oauth/server/oauth2-server.coffee deleted file mode 100644 index 2a5abda75c9b..000000000000 --- a/packages/rocketchat-oauth2-server-config/oauth/server/oauth2-server.coffee +++ /dev/null @@ -1,82 +0,0 @@ -oauth2server = new OAuth2Server - accessTokensCollectionName: 'rocketchat_oauth_access_tokens' - refreshTokensCollectionName: 'rocketchat_oauth_refresh_tokens' - authCodesCollectionName: 'rocketchat_oauth_auth_codes' - clientsCollection: RocketChat.models.OAuthApps.model - debug: true - - -WebApp.connectHandlers.use oauth2server.app - -oauth2server.routes.get '/oauth/userinfo', (req, res, next) -> - if not req.headers.authorization? - return res.sendStatus(401).send('No token') - - accessToken = req.headers.authorization.replace('Bearer ', '') - - token = oauth2server.oauth.model.AccessTokens.findOne accessToken: accessToken - - if not token? - return res.sendStatus(401).send('Invalid Token') - - user = RocketChat.models.Users.findOneById(token.userId); - - if not user? - return res.sendStatus(401).send('Invalid Token') - - res.send - sub: user._id - name: user.name - email: user.emails[0].address - email_verified: user.emails[0].verified - department: "" - birthdate: "" - preffered_username: user.username - updated_at: user._updatedAt - picture: "#{Meteor.absoluteUrl()}avatar/#{user.username}" - - -Meteor.publish 'oauthClient', (clientId) -> - unless @userId - return @ready() - - return RocketChat.models.OAuthApps.find {clientId: clientId, active: true}, - fields: - name: 1 - - -RocketChat.API.v1.addAuthMethod -> - headerToken = @request.headers['authorization'] - getToken = @request.query.access_token - - if headerToken? - if matches = headerToken.match(/Bearer\s(\S+)/) - headerToken = matches[1] - else - headerToken = undefined - - bearerToken = headerToken or getToken - - if not bearerToken? - # console.log 'token not found'.red - return - - # console.log 'bearerToken', bearerToken - - getAccessToken = Meteor.wrapAsync oauth2server.oauth.model.getAccessToken, oauth2server.oauth.model - accessToken = getAccessToken bearerToken - - if not accessToken? - # console.log 'accessToken not found'.red - return - - if accessToken.expires? and accessToken.expires isnt 0 and accessToken.expires < new Date() - # console.log 'accessToken expired'.red - return - - user = RocketChat.models.Users.findOne(accessToken.userId) - if not user? - # console.log 'user not found'.red - return - - return user: _.omit(user, '$loki') diff --git a/packages/rocketchat-oauth2-server-config/oauth/server/oauth2-server.js b/packages/rocketchat-oauth2-server-config/oauth/server/oauth2-server.js new file mode 100644 index 000000000000..a93f9ae4baf0 --- /dev/null +++ b/packages/rocketchat-oauth2-server-config/oauth/server/oauth2-server.js @@ -0,0 +1,83 @@ +/*global OAuth2Server */ + +const oauth2server = new OAuth2Server({ + accessTokensCollectionName: 'rocketchat_oauth_access_tokens', + refreshTokensCollectionName: 'rocketchat_oauth_refresh_tokens', + authCodesCollectionName: 'rocketchat_oauth_auth_codes', + clientsCollection: RocketChat.models.OAuthApps.model, + debug: true +}); + +WebApp.connectHandlers.use(oauth2server.app); + +oauth2server.routes.get('/oauth/userinfo', function(req, res) { + if (req.headers.authorization == null) { + return res.sendStatus(401).send('No token'); + } + const accessToken = req.headers.authorization.replace('Bearer ', ''); + const token = oauth2server.oauth.model.AccessTokens.findOne({ + accessToken + }); + if (token == null) { + return res.sendStatus(401).send('Invalid Token'); + } + const user = RocketChat.models.Users.findOneById(token.userId); + if (user == null) { + return res.sendStatus(401).send('Invalid Token'); + } + return res.send({ + sub: user._id, + name: user.name, + email: user.emails[0].address, + email_verified: user.emails[0].verified, + department: '', + birthdate: '', + preffered_username: user.username, + updated_at: user._updatedAt, + picture: `${ Meteor.absoluteUrl() }avatar/${ user.username }` + }); +}); + +Meteor.publish('oauthClient', function(clientId) { + if (!this.userId) { + return this.ready(); + } + return RocketChat.models.OAuthApps.find({ + clientId, + active: true + }, { + fields: { + name: 1 + } + }); +}); + +RocketChat.API.v1.addAuthMethod(function() { + let headerToken = this.request.headers['authorization']; + const getToken = this.request.query.access_token; + if (headerToken != null) { + const matches = headerToken.match(/Bearer\s(\S+)/); + if (matches) { + headerToken = matches[1]; + } else { + headerToken = undefined; + } + } + const bearerToken = headerToken || getToken; + if (bearerToken == null) { + return; + } + const getAccessToken = Meteor.wrapAsync(oauth2server.oauth.model.getAccessToken, oauth2server.oauth.model); + const accessToken = getAccessToken(bearerToken); + if (accessToken == null) { + return; + } + if ((accessToken.expires != null) && accessToken.expires !== 0 && accessToken.expires < new Date()) { + return; + } + const user = RocketChat.models.Users.findOne(accessToken.userId); + if (user == null) { + return; + } + return { user: _.omit(user, '$loki') }; +}); diff --git a/packages/rocketchat-oauth2-server-config/package.js b/packages/rocketchat-oauth2-server-config/package.js index 1123513df500..6fa2af8525d2 100644 --- a/packages/rocketchat-oauth2-server-config/package.js +++ b/packages/rocketchat-oauth2-server-config/package.js @@ -6,7 +6,6 @@ Package.describe({ Package.onUse(function(api) { api.use('webapp'); - api.use('coffeescript'); api.use('mongo'); api.use('ecmascript'); api.use('rocketchat:lib'); @@ -20,33 +19,33 @@ Package.onUse(function(api) { //// General // // Server - api.addFiles('server/models/OAuthApps.coffee', 'server'); + api.addFiles('server/models/OAuthApps.js', 'server'); //// OAuth // // Server - api.addFiles('oauth/server/oauth2-server.coffee', 'server'); - api.addFiles('oauth/server/default-services.coffee', 'server'); + api.addFiles('oauth/server/oauth2-server.js', 'server'); + api.addFiles('oauth/server/default-services.js', 'server'); api.addFiles('oauth/client/stylesheets/oauth2.less', 'client'); // Client api.addFiles('oauth/client/oauth2-client.html', 'client'); - api.addFiles('oauth/client/oauth2-client.coffee', 'client'); + api.addFiles('oauth/client/oauth2-client.js', 'client'); //// Admin // // Client - api.addFiles('admin/client/startup.coffee', 'client'); - api.addFiles('admin/client/collection.coffee', 'client'); - api.addFiles('admin/client/route.coffee', 'client'); + api.addFiles('admin/client/startup.js', 'client'); + api.addFiles('admin/client/collection.js', 'client'); + api.addFiles('admin/client/route.js', 'client'); api.addFiles('admin/client/views/oauthApp.html', 'client'); - api.addFiles('admin/client/views/oauthApp.coffee', 'client'); + api.addFiles('admin/client/views/oauthApp.js', 'client'); api.addFiles('admin/client/views/oauthApps.html', 'client'); - api.addFiles('admin/client/views/oauthApps.coffee', 'client'); + api.addFiles('admin/client/views/oauthApps.js', 'client'); // Server - api.addFiles('admin/server/publications/oauthApps.coffee', 'server'); - api.addFiles('admin/server/methods/addOAuthApp.coffee', 'server'); - api.addFiles('admin/server/methods/updateOAuthApp.coffee', 'server'); - api.addFiles('admin/server/methods/deleteOAuthApp.coffee', 'server'); + api.addFiles('admin/server/publications/oauthApps.js', 'server'); + api.addFiles('admin/server/methods/addOAuthApp.js', 'server'); + api.addFiles('admin/server/methods/updateOAuthApp.js', 'server'); + api.addFiles('admin/server/methods/deleteOAuthApp.js', 'server'); }); diff --git a/packages/rocketchat-oauth2-server-config/server/models/OAuthApps.coffee b/packages/rocketchat-oauth2-server-config/server/models/OAuthApps.coffee deleted file mode 100644 index 62bc4b7db342..000000000000 --- a/packages/rocketchat-oauth2-server-config/server/models/OAuthApps.coffee +++ /dev/null @@ -1,13 +0,0 @@ -RocketChat.models.OAuthApps = new class extends RocketChat.models._Base - constructor: -> - super('oauth_apps') - - - # FIND - # findByRole: (role, options) -> - # query = - # roles: role - - # return @find query, options - - # CREATE diff --git a/packages/rocketchat-oauth2-server-config/server/models/OAuthApps.js b/packages/rocketchat-oauth2-server-config/server/models/OAuthApps.js new file mode 100644 index 000000000000..46c70d55f9eb --- /dev/null +++ b/packages/rocketchat-oauth2-server-config/server/models/OAuthApps.js @@ -0,0 +1,17 @@ +RocketChat.models.OAuthApps = new class extends RocketChat.models._Base { + constructor() { + super('oauth_apps'); + } +}; + + + + + // FIND + // findByRole: (role, options) -> + // query = + // roles: role + + // return @find query, options + + // CREATE