diff --git a/app/app.js b/app/app.js index e54e9a501..92130fa5b 100644 --- a/app/app.js +++ b/app/app.js @@ -79,10 +79,10 @@ const App = Application.extend({ 'digitalOcean', 'endpoint', 'github', - 'google', 'globalStore', 'intl', 'modal', + 'oauth', 'resource-actions', 'router', 'scope', diff --git a/app/verify-auth/route.js b/app/verify-auth/route.js index 800ebedb7..e7cff8cab 100644 --- a/app/verify-auth/route.js +++ b/app/verify-auth/route.js @@ -11,8 +11,7 @@ const samlProviders = ['ping', 'adfs', 'keycloak', 'okta']; const allowedForwards = ['localhost']; export default Route.extend(VerifyAuth, { - github: service(), - google: service(), + oauth: service(), intl: service(), language: service('user-language'), @@ -23,8 +22,7 @@ export default Route.extend(VerifyAuth, { }, model(params/* , transition */) { - const github = get(this, 'github'); - const google = get(this, 'google'); + const oauth = get(this, 'oauth'); const code = get(params, 'code'); const forward = get(params, 'forward'); @@ -41,7 +39,7 @@ export default Route.extend(VerifyAuth, { code }); } else { - github.login(forward); + oauth.login(forward); } } else { return reject(new Error('Invalid forward url')); @@ -51,28 +49,21 @@ export default Route.extend(VerifyAuth, { } if ( window.opener && !get(params, 'login') && !get(params, 'errorCode') ) { - let openersGithub = window.opener.ls('github'); - let openersGoogle = window.opener.ls('google'); + let openersOauth = window.opener.ls('oauth'); let openerStore = window.opener.ls('globalStore'); let qp = get(params, 'config') || get(params, 'authProvider'); let type = `${ qp }Config`; let config = openerStore.getById(type, qp); - let gh = get(this, 'github'); - let go = get(this, 'google'); let stateMsg = 'Authorization state did not match, please try again.'; + let isGithub = get(params, 'config') === 'github' + let isGoogle = get(params, 'config') === 'googleoauth' - if ( get(params, 'config') === 'github' ) { - return gh.testConfig(config).then((resp) => { - gh.authorize(resp, openersGithub.get('state')); + if ( isGithub || isGoogle ) { + return oauth.testConfig(config).then((resp) => { + oauth.authorize(resp, openersOauth.get('state')); }).catch((err) => { this.send('gotError', err); }); - } else if ( get(params, 'config') === 'googleoauth') { - return go.testConfig(config).then((resp) => { - go.authorize(resp, openersGoogle.get('state')); - }).catch((err) => { - this.send('gotError', err) - }) } else if ( samlProviders.includes(get(params, 'config')) ) { if ( window.opener.window.onAuthTest ) { reply(null, config); @@ -82,9 +73,7 @@ export default Route.extend(VerifyAuth, { } if ( get(params, 'code') ) { - const currentOpener = openersGithub.state ? openersGithub : openersGoogle; - - if ( currentOpener.stateMatches(get(params, 'state')) ) { + if ( openersOauth.stateMatches(get(params, 'state')) ) { reply(params.error_description, params.code); } else { reply(stateMsg); @@ -99,11 +88,11 @@ export default Route.extend(VerifyAuth, { } } - if ( code && get(params, 'login') || get(params, 'state').includes('login') ) { - let currentProvider = github.stateMatches(get(params, 'state')) ? 'github' : 'googleoauth' + if ( code && get(params, 'state').includes('login') ) { + const providerType = get(params, 'state').includes('github') ? 'github' : 'googleoauth' - if ( github.stateMatches(get(params, 'state')) || google.stateMatches(get(params, 'state')) ) { - currentProvider = get(this, 'access.providers').findBy('id', currentProvider); + if ( oauth.stateMatches(get(params, 'state')) ) { + const currentProvider = get(this, 'access.providers').findBy('id', providerType); return currentProvider.doAction('login', { code, diff --git a/lib/global-admin/addon/engine.js b/lib/global-admin/addon/engine.js index a7ac984d8..5b498b706 100644 --- a/lib/global-admin/addon/engine.js +++ b/lib/global-admin/addon/engine.js @@ -18,10 +18,10 @@ const Eng = Engine.extend({ 'digitalOcean', 'endpoint', 'github', - 'google', 'globalStore', 'intl', 'modal', + 'oauth', 'resource-actions', 'router', 'scope', diff --git a/lib/global-admin/addon/security/authentication/github/controller.js b/lib/global-admin/addon/security/authentication/github/controller.js index 112423ef5..25d9be51b 100644 --- a/lib/global-admin/addon/security/authentication/github/controller.js +++ b/lib/global-admin/addon/security/authentication/github/controller.js @@ -9,7 +9,7 @@ import C from 'ui/utils/constants'; import AuthMixin from 'global-admin/mixins/authentication'; export default Controller.extend(AuthMixin, { - github: service(), + oauth: service(), endpoint: service(), access: service(), settings: service(), @@ -58,7 +58,7 @@ export default Controller.extend(AuthMixin, { 'allowedPrincipalIds': [], }); - setProperties(get(this, 'github'), { + setProperties(get(this, 'oauth'), { hostname: authConfig.get('hostname'), scheme: authConfig.get('scheme'), clientId: authConfig.get('clientId') @@ -66,7 +66,7 @@ export default Controller.extend(AuthMixin, { set(this, '_boundSucceed', this.authenticationApplied.bind(this)); - get(this, 'github').test(authConfig, get(this, '_boundSucceed')); + get(this, 'oauth').test(authConfig, get(this, '_boundSucceed')); }, }, enterpriseDidChange: observer('isEnterprise', 'authConfig.hostname', 'secure', function() { diff --git a/lib/global-admin/addon/security/authentication/googleoauth/controller.js b/lib/global-admin/addon/security/authentication/googleoauth/controller.js index 7173a9bfa..354f24954 100644 --- a/lib/global-admin/addon/security/authentication/googleoauth/controller.js +++ b/lib/global-admin/addon/security/authentication/googleoauth/controller.js @@ -5,7 +5,7 @@ import Controller from '@ember/controller'; import AuthMixin from 'global-admin/mixins/authentication'; export default Controller.extend(AuthMixin, { - google: service(), + oauth: service(), endpoint: service(), access: service(), settings: service(), @@ -44,7 +44,7 @@ export default Controller.extend(AuthMixin, { }); set(this, '_boundSucceed', this.authenticationApplied.bind(this)); - get(this, 'google').test(authConfig, get(this, '_boundSucceed')); + get(this, 'oauth').test(authConfig, get(this, '_boundSucceed')); }, }, diff --git a/lib/global-admin/addon/security/authentication/googleoauth/template.hbs b/lib/global-admin/addon/security/authentication/googleoauth/template.hbs index 4559c8e82..43906ef90 100644 --- a/lib/global-admin/addon/security/authentication/googleoauth/template.hbs +++ b/lib/global-admin/addon/security/authentication/googleoauth/template.hbs @@ -1,11 +1,10 @@
{{#unless isEnabled}} - + {{/unless}} {{top-errors errors=errors}}
@@ -21,21 +20,21 @@ showExpand=false title=(t 'authPage.google.authenticated.header.text') }} -
-
-
-

-
{{t 'authPage.google.authenticated.header.adminEmail.text'}} {{authConfig.adminEmail}}
+
{{t 'authPage.google.authenticated.header.adminEmail.text'}} {{authConfig.adminEmail}}
{{/accordion-list-item}} {{#accordion-list-item - classNames="mt-30" + classNames='mt-30' detail=(t 'siteAccess.helpText' appName=settings.appName htmlSafe=true) expand=(action expandFn) expandAll=al.expandAll @@ -61,9 +60,9 @@ showExpand=false title=(t 'authPage.google.notAuthenticated.header') }} -
+

-

    +
    1. {{t 'authPage.google.notAuthenticated.ul.li1.text' htmlSafe=true}}
        @@ -74,10 +73,25 @@ {{t 'authPage.google.notAuthenticated.ul.li2.text'}}
        • {{t 'authPage.google.notAuthenticated.ul.li2.ul.li1' appName=settings.appName htmlSafe=true}} - {{destinationDomain}}{{copy-to-clipboard size='small' clipboardText=destinationUrl htmlSafe=true}} + + {{destinationDomain}} + {{copy-to-clipboard + size='small' + clipboardText=destinationUrl + htmlSafe=true + }} +
        • - {{t 'authPage.google.notAuthenticated.ul.li2.ul.li2' htmlSafe=true}} {{destinationUrl}}{{copy-to-clipboard size='small' clipboardText=destinationUrl htmlSafe=true}} + {{t 'authPage.google.notAuthenticated.ul.li2.ul.li2' htmlSafe=true}} + + {{destinationUrl}} + {{copy-to-clipboard + size='small' + clipboardText=destinationUrl + htmlSafe=true + }} +
        • {{t 'authPage.google.notAuthenticated.ul.li2.ul.li3'}}
        @@ -88,10 +102,25 @@
      • {{t 'authPage.google.notAuthenticated.ul.li3.ul.li1'}}
      • - {{t 'authPage.google.notAuthenticated.ul.li3.ul.li2' htmlSafe=true}} {{destinationUrl}}{{copy-to-clipboard size='small' clipboardText=destinationUrl htmlSafe=true}} + {{t 'authPage.google.notAuthenticated.ul.li3.ul.li2' htmlSafe=true}} + + {{destinationUrl}} + {{copy-to-clipboard + size='small' + clipboardText=destinationUrl + htmlSafe=true + }} +
      • {{t 'authPage.google.notAuthenticated.ul.li3.ul.li3' htmlSafe=true}} - {{redirectURI}}{{copy-to-clipboard size='small' clipboardText=destinationUrl htmlSafe=true}} + + {{redirectURI}} + {{copy-to-clipboard + size='small' + clipboardText=destinationUrl + htmlSafe=true + }} +
      • {{t 'authPage.google.notAuthenticated.ul.li3.ul.li4'}}
      @@ -118,44 +147,53 @@ showExpand=false title=(t 'authPage.google.notAuthenticated.form.header' appName=settings.appName) }} -
      -
      + +
      -
      -
      -
      - - {{input type="text" name="username" value=authConfig.adminEmail classNames="form-control"}} -

      {{t 'authPage.google.notAuthenticated.form.adminEmail.helperText'}}

      +
      +
      +
      + + {{input + type='text' + name='username' + value=authConfig.adminEmail + classNames='form-control' + }} +

      {{t 'authPage.google.notAuthenticated.form.adminEmail.helperText'}}

      -
      -
      - - {{input type="text" value=authConfig.hostname classNames="form-control"}} -

      {{t 'authPage.google.notAuthenticated.form.hostname.helperText'}}

      +
      +
      + + {{input + type='text' + value=authConfig.hostname + classNames='form-control' + }} +

      {{t 'authPage.google.notAuthenticated.form.hostname.helperText'}}

      -
      -
      +
      +
      {{#input-text-file - classNames="box" - label="authPage.google.notAuthenticated.form.oauthCredential.labelText" + classNames='box' + label='authPage.google.notAuthenticated.form.oauthCredential.labelText' value=authConfig.oauthCredential - accept="text/*, .json" + accept='text/*, .json' minHeight=60 canChangeName=false nameRequired=true - placeholder="authPage.google.notAuthenticated.form.oauthCredential.labelText" + placeholder='authPage.google.notAuthenticated.form.oauthCredential.labelText' concealValue=true as |section| }} - {{#if (eq section "description")}} -
      -
      - {{t "authPage.google.notAuthenticated.form.oauthCredential.helperText" htmlSafe=true}} + {{#if (eq section 'description')}} +
      +
      + {{t 'authPage.google.notAuthenticated.form.oauthCredential.helperText' htmlSafe=true}}
      {{/if}} @@ -163,24 +201,24 @@
      -
      -
      +
      +
      {{#input-text-file - classNames="box" - label="authPage.google.notAuthenticated.form.serviceAccountCredential.labelText" + classNames='box' + label='authPage.google.notAuthenticated.form.serviceAccountCredential.labelText' value=authConfig.serviceAccountCredential - accept="text/*, .json" + accept='text/*, .json' minHeight=60 canChangeName=false nameRequired=true - placeholder="authPage.google.notAuthenticated.form.serviceAccountCredential.labelText" + placeholder='authPage.google.notAuthenticated.form.serviceAccountCredential.labelText' concealValue=true as |section| }} - {{#if (eq section "description")}} -
      -
      - {{t "authPage.google.notAuthenticated.form.serviceAccountCredential.helperText" htmlSafe=true}} + {{#if (eq section 'description')}} +
      +
      + {{t 'authPage.google.notAuthenticated.form.serviceAccountCredential.helperText' htmlSafe=true}}
      {{/if}} @@ -188,18 +226,18 @@
      -
      -
      - - +
      diff --git a/lib/login/addon/components/login-github/component.js b/lib/login/addon/components/login-github/component.js index 722fa6874..97743a8d9 100644 --- a/lib/login/addon/components/login-github/component.js +++ b/lib/login/addon/components/login-github/component.js @@ -2,11 +2,11 @@ import { inject as service } from '@ember/service'; import Component from '@ember/component'; export default Component.extend({ - github: service(), + oauth: service(), actions: { authenticate() { - this.get('github').login(); + this.get('oauth').login('github'); } } }); diff --git a/lib/login/addon/components/login-google/component.js b/lib/login/addon/components/login-google/component.js index a4d197dc5..5325c1618 100644 --- a/lib/login/addon/components/login-google/component.js +++ b/lib/login/addon/components/login-google/component.js @@ -2,11 +2,11 @@ import { inject as service } from '@ember/service'; import Component from '@ember/component'; export default Component.extend({ - google: service(), + oauth: service(), actions: { authenticate() { - this.get('google').login(); + this.get('oauth').login('googleoauth'); } } }); diff --git a/lib/login/addon/components/login-google/template.hbs b/lib/login/addon/components/login-google/template.hbs index e8e118063..1309264ea 100644 --- a/lib/login/addon/components/login-google/template.hbs +++ b/lib/login/addon/components/login-google/template.hbs @@ -1,5 +1,5 @@ diff --git a/lib/shared/addon/github/service.js b/lib/shared/addon/github/service.js index 32d8e37e9..70295ea94 100644 --- a/lib/shared/addon/github/service.js +++ b/lib/shared/addon/github/service.js @@ -3,6 +3,9 @@ import { addQueryParam, addQueryParams, popupWindowOptions } from 'shared/utils/ import { get, set } from '@ember/object'; import C from 'shared/utils/constants'; +const googleOauthScope = 'openid profile email https://www.googleapis.com/auth/admin.directory.user.readonly https://www.googleapis.com/auth/admin.directory.group.readonly'; +const githubOauthScope = 'read:org'; + export default Service.extend({ access: service(), cookies: service(), @@ -10,11 +13,16 @@ export default Service.extend({ globalStore: service(), app: service(), intl: service(), + authType: '', generateState() { return set(this, 'session.githubState', `${ Math.random() }`); }, + generateLoginStateKey(authType) { + return set(this, 'session.githubState', `${ Math.random() }login${ authType }`) + }, + stateMatches(actual) { return actual && get(this, 'session.githubState') === actual; }, @@ -28,31 +36,41 @@ export default Service.extend({ }, authorize(auth, state) { - const url = addQueryParams(get(auth, 'redirectUrl'), { - scope: 'read:org', - redirect_uri: `${ window.location.origin }/verify-auth`, - authProvider: 'github', - state, - }); + const isGithub = auth.type.includes('github') + let url = null; + + + if (isGithub) { + url = addQueryParams(get(auth, 'redirectUrl'), { + scope: githubOauthScope, + redirect_uri: `${ window.location.origin }/verify-auth`, + authProvider: 'github', + state, + }); + } else { + url = addQueryParams(get(auth, 'redirectUrl'), { + scope: googleOauthScope, + redirect_uri: `${ window.location.origin }/verify-auth`, + state, + }); + } return window.location.href = url; }, - login(forwardUrl) { - const provider = get(this, 'access.providers').findBy('id', 'github'); + login(authType, forwardUrl) { + const provider = get(this, 'access.providers').findBy('id', authType); const authRedirect = get(provider, 'redirectUrl'); - let redirect = addQueryParams(`${ window.location.origin }/verify-auth`, { - login: true, - state: this.generateState(), - }); + let redirect = `${ window.location.origin }/verify-auth`; if ( forwardUrl ) { redirect = addQueryParam(redirect, 'forward', forwardUrl); } - const url = addQueryParams(authRedirect, { - scope: 'read:org', - redirect_uri: redirect, + let url = addQueryParams(authRedirect, { + scope: authType === 'github' ? githubOauthScope : googleOauthScope, + state: this.generateLoginStateKey(authType), + redirect_uri: redirect, }); window.location.href = url; @@ -60,6 +78,7 @@ export default Service.extend({ test(config, cb) { let responded = false; + let configName = config.name; window.onAuthTest = (err, code) => { if ( !responded ) { @@ -72,8 +91,7 @@ export default Service.extend({ }; set(this, 'state', this.generateState()); - - let url = addQueryParams(`${ window.location.origin }/verify-auth`, { config: 'github', }); + let url = addQueryParams(`${ window.location.origin }/verify-auth`, { config: configName, }); const popup = window.open(url, 'rancherAuth', popupWindowOptions()); const intl = get(this, 'intl'); @@ -105,17 +123,28 @@ export default Service.extend({ }, finishTest(config, code, cb) { - const ghConfig = config; + const currentConfig = config; + let out = null; - set(ghConfig, 'enabled', true); + set(currentConfig, 'enabled', true); - let out = { - code, - enabled: true, - githubConfig: ghConfig, - description: C.SESSION.DESCRIPTION, - ttl: C.SESSION.TTL, - }; + if (config.id === 'googleoauth') { + out = { + code, + enabled: true, + googleOauthConfig: currentConfig, + description: C.SESSION.DESCRIPTION, + ttl: C.SESSION.TTL, + }; + } else { + out = { + code, + enabled: true, + githubConfig: currentConfig, + description: C.SESSION.DESCRIPTION, + ttl: C.SESSION.TTL, + }; + } const allowedPrincipalIds = get(config, 'allowedPrincipalIds') || []; @@ -133,7 +162,7 @@ export default Service.extend({ allowedPrincipalIds.pushObject(get(this, 'access.principal.id')); } - return ghConfig.save().then(() => { + return currentConfig.save().then(() => { window.location.href = window.location.href; }); }) diff --git a/lib/shared/addon/google/service.js b/lib/shared/addon/oauth/service.js similarity index 58% rename from lib/shared/addon/google/service.js rename to lib/shared/addon/oauth/service.js index cd30c1c4a..70295ea94 100644 --- a/lib/shared/addon/google/service.js +++ b/lib/shared/addon/oauth/service.js @@ -3,7 +3,8 @@ import { addQueryParam, addQueryParams, popupWindowOptions } from 'shared/utils/ import { get, set } from '@ember/object'; import C from 'shared/utils/constants'; -const googleOauthScope = 'openid profile email https://www.googleapis.com/auth/admin.directory.user.readonly https://www.googleapis.com/auth/admin.directory.group.readonly' +const googleOauthScope = 'openid profile email https://www.googleapis.com/auth/admin.directory.user.readonly https://www.googleapis.com/auth/admin.directory.group.readonly'; +const githubOauthScope = 'read:org'; export default Service.extend({ access: service(), @@ -12,17 +13,18 @@ export default Service.extend({ globalStore: service(), app: service(), intl: service(), + authType: '', generateState() { - return set(this, 'session.googleState', `${ Math.random() }`); + return set(this, 'session.githubState', `${ Math.random() }`); }, - generateLoginStateKey() { - return set(this, 'session.googleState', `${ Math.random() }login`) + generateLoginStateKey(authType) { + return set(this, 'session.githubState', `${ Math.random() }login${ authType }`) }, stateMatches(actual) { - return actual && get(this, 'session.googleState') === actual; + return actual && get(this, 'session.githubState') === actual; }, testConfig(config) { @@ -34,18 +36,30 @@ export default Service.extend({ }, authorize(auth, state) { - const url = addQueryParams(get(auth, 'redirectUrl'), { - scope: googleOauthScope, - redirect_uri: `${ window.location.origin }/verify-auth`, - state, - }); + const isGithub = auth.type.includes('github') + let url = null; + if (isGithub) { + url = addQueryParams(get(auth, 'redirectUrl'), { + scope: githubOauthScope, + redirect_uri: `${ window.location.origin }/verify-auth`, + authProvider: 'github', + state, + }); + } else { + url = addQueryParams(get(auth, 'redirectUrl'), { + scope: googleOauthScope, + redirect_uri: `${ window.location.origin }/verify-auth`, + state, + }); + } + return window.location.href = url; }, - login(forwardUrl) { - const provider = get(this, 'access.providers').findBy('id', 'googleoauth'); + login(authType, forwardUrl) { + const provider = get(this, 'access.providers').findBy('id', authType); const authRedirect = get(provider, 'redirectUrl'); let redirect = `${ window.location.origin }/verify-auth`; @@ -53,9 +67,9 @@ export default Service.extend({ redirect = addQueryParam(redirect, 'forward', forwardUrl); } - const url = addQueryParams(authRedirect, { - scope: googleOauthScope, - state: this.generateLoginStateKey(), + let url = addQueryParams(authRedirect, { + scope: authType === 'github' ? githubOauthScope : googleOauthScope, + state: this.generateLoginStateKey(authType), redirect_uri: redirect, }); @@ -64,20 +78,20 @@ export default Service.extend({ test(config, cb) { let responded = false; + let configName = config.name; window.onAuthTest = (err, code) => { if ( !responded ) { - let googleConfig = config; + let ghConfig = config; responded = true; - this.finishTest(googleConfig, code, cb); + this.finishTest(ghConfig, code, cb); } }; set(this, 'state', this.generateState()); - - let url = addQueryParams(`${ window.location.origin }/verify-auth`, { config: 'googleoauth', }); + let url = addQueryParams(`${ window.location.origin }/verify-auth`, { config: configName, }); const popup = window.open(url, 'rancherAuth', popupWindowOptions()); const intl = get(this, 'intl'); @@ -90,7 +104,7 @@ export default Service.extend({ responded = true; cb({ type: 'error', - message: intl.t('authPage.google.testAuth.authError') + message: intl.t('authPage.github.testAuth.authError') }); } } else if (popup === null || typeof (popup) === 'undefined') { @@ -101,7 +115,7 @@ export default Service.extend({ cb({ type: 'error', - message: intl.t('authPage.google.testAuth.popupError') + message: intl.t('authPage.github.testAuth.popupError') }); } } @@ -109,17 +123,28 @@ export default Service.extend({ }, finishTest(config, code, cb) { - const goConfig = config; + const currentConfig = config; + let out = null; - set(goConfig, 'enabled', true); + set(currentConfig, 'enabled', true); - let out = { - code, - enabled: true, - googleOauthConfig: goConfig, - description: C.SESSION.DESCRIPTION, - ttl: C.SESSION.TTL, - }; + if (config.id === 'googleoauth') { + out = { + code, + enabled: true, + googleOauthConfig: currentConfig, + description: C.SESSION.DESCRIPTION, + ttl: C.SESSION.TTL, + }; + } else { + out = { + code, + enabled: true, + githubConfig: currentConfig, + description: C.SESSION.DESCRIPTION, + ttl: C.SESSION.TTL, + }; + } const allowedPrincipalIds = get(config, 'allowedPrincipalIds') || []; @@ -137,7 +162,7 @@ export default Service.extend({ allowedPrincipalIds.pushObject(get(this, 'access.principal.id')); } - return goConfig.save().then(() => { + return currentConfig.save().then(() => { window.location.href = window.location.href; }); }) @@ -145,4 +170,4 @@ export default Service.extend({ cb(err); }); }, -}) +}); diff --git a/lib/shared/addon/utils/constants.js b/lib/shared/addon/utils/constants.js index abef57eb2..c289e3a56 100644 --- a/lib/shared/addon/utils/constants.js +++ b/lib/shared/addon/utils/constants.js @@ -220,6 +220,9 @@ var C = { TYPE_OKTA_GROUP: 'okta_group', TYPE_FREEIPA_USER: 'freeipa_user', TYPE_FREEIPA_GROUP: 'freeipa_group', + TYPE_GOOGLE_USER: 'google_user', + TYPE_GOOGLE_TEAM: 'google_team', + TYPE_GOOGLE_ORG: 'google_org', PERSON: 'person', TEAM: 'team', diff --git a/lib/shared/app/google/service.js b/lib/shared/app/google/service.js deleted file mode 100644 index e8bf42af0..000000000 --- a/lib/shared/app/google/service.js +++ /dev/null @@ -1 +0,0 @@ -export { default } from 'shared/google/service'; diff --git a/lib/shared/app/oauth/service.js b/lib/shared/app/oauth/service.js new file mode 100644 index 000000000..8e8949ba4 --- /dev/null +++ b/lib/shared/app/oauth/service.js @@ -0,0 +1 @@ +export { default } from 'shared/oauth/service'; diff --git a/vendor/icons b/vendor/icons index dc7c43854..3781f899f 160000 --- a/vendor/icons +++ b/vendor/icons @@ -1 +1 @@ -Subproject commit dc7c438544167077ea087bd594921c0d12e7b182 +Subproject commit 3781f899f1f430fa7af78642e89055d4da2695db