-
Notifications
You must be signed in to change notification settings - Fork 10.9k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[IMPROVE] Support for Google OAuth for mobile app #22014
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,92 @@ | ||
import { Meteor } from 'meteor/meteor'; | ||
import { OAuth } from 'meteor/oauth'; | ||
|
||
// The code on this file was copied directly from Meteor and modified to support mobile google oauth | ||
// https://github.com/meteor/meteor/blob/ffcfa5062cf1bf8a64ea64fef681ffcd99fe7939/packages/oauth/oauth_server.js | ||
|
||
Meteor.startup(() => { | ||
const appRedirectUrl = 'rocketchat://auth'; | ||
|
||
const renderEndOfLoginResponse = (options) => { | ||
const escape = (s) => { | ||
if (!s) { | ||
return s; | ||
} | ||
|
||
return s.replace(/&/g, '&').replace(/</g, '<').replace(/>/g, '>').replace(/\'/g, '"').replace(/\'/g, ''').replace(/\//g, '/'); | ||
}; | ||
|
||
const config = { | ||
setCredentialToken: !! options.setCredentialToken, | ||
credentialToken: escape(options.credentialToken), | ||
credentialSecret: escape(options.credentialSecret), | ||
storagePrefix: escape(OAuth._storageTokenPrefix), | ||
redirectUrl: escape(options.redirectUrl), | ||
isCordova: !! options.isCordova, | ||
}; | ||
|
||
let template; | ||
if (options.loginStyle === 'popup') { | ||
template = OAuth._endOfPopupResponseTemplate; | ||
} else if (options.loginStyle === 'redirect') { | ||
template = OAuth._endOfRedirectResponseTemplate; | ||
} else { | ||
throw new Error(`invalid loginStyle: ${ options.loginStyle }`); | ||
} | ||
|
||
const result = template.replace(/##CONFIG##/, JSON.stringify(config)).replace(/##ROOT_URL_PATH_PREFIX##/, __meteor_runtime_config__.ROOT_URL_PATH_PREFIX); | ||
|
||
return `<!DOCTYPE html>\n${ result }`; | ||
}; | ||
|
||
OAuth._endOfLoginResponse = (res, details) => { | ||
res.writeHead(200, { 'Content-Type': 'text/html' }); | ||
let redirectUrl; | ||
|
||
if (details.loginStyle === 'redirect') { | ||
redirectUrl = OAuth._stateFromQuery(details.query).redirectUrl; | ||
const appHost = Meteor.absoluteUrl(); | ||
|
||
if (redirectUrl.startsWith(appRedirectUrl)) { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. we might need to think a way to have this custom code easier to spot and maintain. Let's say on next Meteor version this code changes and we need to copy the new code over here, it might be not that easy to spot our changes and keep them. |
||
redirectUrl = `${ appRedirectUrl }?host=${ appHost }&type=oauth`; | ||
|
||
if (details.error) { | ||
const error = encodeURIComponent(details.error.toString()); | ||
redirectUrl = `${ redirectUrl }&error=${ error }`; | ||
} | ||
|
||
if (details.credentials) { | ||
const { token, secret } = details.credentials; | ||
redirectUrl = `${ redirectUrl }&credentialToken=${ token }&credentialSecret=${ secret }`; | ||
} | ||
} else if (!Meteor.settings?.packages?.oauth?.disableCheckRedirectUrlOrigin && OAuth._checkRedirectUrlOrigin(redirectUrl)) { | ||
details.error = `redirectUrl (${ redirectUrl }) is not on the same host as the app (${ appHost })`; | ||
redirectUrl = appHost; | ||
} | ||
} | ||
|
||
const isCordova = OAuth._isCordovaFromQuery(details.query); | ||
|
||
if (details.error) { | ||
res.end(renderEndOfLoginResponse({ | ||
loginStyle: details.loginStyle, | ||
setCredentialToken: false, | ||
redirectUrl, | ||
isCordova, | ||
}), 'utf-8'); | ||
return; | ||
} | ||
|
||
// If we have a credentialSecret, report it back to the parent | ||
// window, with the corresponding credentialToken. The parent window | ||
// uses the credentialToken and credentialSecret to log in over DDP. | ||
res.end(renderEndOfLoginResponse({ | ||
loginStyle: details.loginStyle, | ||
setCredentialToken: true, | ||
credentialToken: details.credentials.token, | ||
credentialSecret: details.credentials.secret, | ||
redirectUrl, | ||
isCordova, | ||
}), 'utf-8'); | ||
}; | ||
}); |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -27,6 +27,7 @@ import '../app/file'; | |
import '../app/file-upload'; | ||
import '../app/github-enterprise/server'; | ||
import '../app/gitlab/server'; | ||
import '../app/google-oauth/server'; | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. we should not create new things inside since this is overwriting Meteor's internal functions, maybe we could make that explicit making it easier to spot possible issues when updating Meteor.. maybe something like There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. What about |
||
import '../app/google-vision/server'; | ||
import '../app/iframe-login/server'; | ||
import '../app/importer/server'; | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
any special reason to have this in a
Meteor.startup
? Otherwise I'd remove it.