Skip to content
This repository has been archived by the owner on Jun 27, 2019. It is now read-only.

zapier convert: Generate different auth code based on scripting #185

Merged
merged 11 commits into from
Nov 28, 2017

Conversation

eliangcs
Copy link
Member

@eliangcs eliangcs commented Nov 15, 2017

Summary:

  • Move authentication code from index.js to its own separate file authentication.js
  • Generate different auth code based on scripting, including:
    • OAuth: generate a getAccessToken() if pre_oauthv2_token or post_oauthv2_token method exists
    • OAuth: generate a refreshAccessToken() if pre_oauthv2_refresh method exists
    • Session: generate a getSessionKey() that invokes get_session_info method
    • Generate a getConnectionLabel() if get_connection_label method exists

See more detail in the following comments.

@eliangcs eliangcs changed the title zapier convert: Generate different auth code based on scripting [WIP] zapier convert: Generate different auth code based on scripting Nov 15, 2017
const AuthTest = { operation: { perform: 'FAKE_PERFORM_FUNCTION' } };
const getSessionKey = 'FAKE_GET_SESSION_KEY_FUNCTION';
(${string});
`);
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Since now I'm using loadAuthModuleFromString to eval the generated auth code, we don't need AuthTest and getSessionKey in s2js.

const convert = require('../../utils/convert');
const definitions = {
basic: require('./definitions/basic.json'),
basicScripting: require('./definitions/basic-scripting.json'),
Copy link
Member Author

@eliangcs eliangcs Nov 16, 2017

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

basic-scripting.json is same as basic.json except that it has a get_connection_info method in scripting.

apiHeader: require('./definitions/api-header.json'),
apiQuery: require('./definitions/api-query.json'),
session: require('./definitions/session.json'),
oauth2: require('./definitions/oauth2.json'),
oauth2Scripting: require('./definitions/oauth2-scripting.json'),
Copy link
Member Author

@eliangcs eliangcs Nov 16, 2017

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

oauth2-scripting.json is same as oauth2.json except that it defines pre_oauthv2_token and post_oauthv2_token method in scripting.

oauth2Refresh: require('./definitions/oauth2-refresh.json'),
oauth2RefreshScripting: require('./definitions/oauth2-refresh-scripting.json'),
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

oauth2-refresh-scripting.json is same as oauth2-refresh.json except that it defines pre_oauthv2_token, post_oauthv2_token and pre_oauthv2_refresh method in scripting.

const wbDef = definitions.basic;

convert.renderAuth(wbDef)
return convert.renderAuth(wbDef)
Copy link
Member Author

@eliangcs eliangcs Nov 16, 2017

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

To make the code cleaner, instead of using done() callback, I changed the style of all the auth-related tests by simply returning a Promise.

}
]);
auth.connectionLabel.should.eql('{{username}}');
auth.test().should.eql('./triggers/test_auth');
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This test trigger is mocked so that it returns the module path. See loadAuthModuleFromString().

@@ -495,15 +559,13 @@ const renderIndex = (legacyApp) => {
AFTER_RESPONSES: getAfterResponses(legacyApp),
};

return renderAuth(legacyApp)
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Authentication has been moved to its own separate file authentication.js, so we no longer need to call renderAuth() when rendering index.js.

@@ -67,6 +68,7 @@
"mocha": "3.4.2",
"ngrok": "2.2.10",
"node-watch": "0.5.4",
"require-from-string": "2.0.1",
Copy link
Member Author

@eliangcs eliangcs Nov 16, 2017

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This package is used to load the rendered auth code, i.e., authentication.js. Since authentication.js is a CommonJS module (with module.exports = ... ; at the end), we can't just use s2js() or eval() to evaluate the code. require-from-string allows us to do require() but from a string instead of a file.


if (cliType === 'trigger' && _.get(legacyApp, ['general', 'test_trigger_key']) === name) {
importLines.push(`const AuthTest = ${varName};`);
}
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Test trigger is now imported in authentication.js, so we can remove it from index.js.

@eliangcs eliangcs changed the title [WIP] zapier convert: Generate different auth code based on scripting zapier convert: Generate different auth code based on scripting Nov 16, 2017
Copy link
Contributor

@BrunoBernardino BrunoBernardino left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is amazing @eliangcs ! Awesome tests, refactoring for re-usability, and things are looking neat!

I've got a few suggestions and requests, but it's nothing really major.

<%= FIELDS %>
],
<% if (hasGetConnectionLabelScripting) { %>
connectionLabel: getConnectionLabel,
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

For consistency, I'd expect this to not have a trailing comma, since the else doesn't as well.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed in 73e2c37.

const testTrigger = require('<%= TEST_TRIGGER_MODULE %>');
<% if (hasGetConnectionLabelScripting) { %>
const getConnectionLabel = (z, bundle) => {
const scripting = require('../scripting');
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I believe this isn't running from a folder, so scripting.js should be at the same level, not one level above?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nice catch! Fixed in ecb1a36.

const testTrigger = require('<%= TEST_TRIGGER_MODULE %>');
<% if (hasPreOAuthTokenScripting && hasPostOAuthTokenScripting) { %>
const getAccessToken = (z, bundle) => {
const scripting = require('../scripting');
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same comment as above with the relative location of scripting.js.

@@ -86,7 +87,7 @@ const getAuthType = (definition) => {
return authTypeMap[definition.general.auth_type];
};

const renderField = (definition, key) => {
const renderField = (definition, key, indent = 0) => {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nice!

};

const renderFields = (fields, indent = 0) => {
const result = [];
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'd prefer to make this plural results just to more clearly indicate it's a list of things, not a single thing/object.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed in 990f1c9.


if (hasGetConnectionLabelScripting) { %>
const getConnectionLabel = (z, bundle) => {
const scripting = require('../scripting');
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same comment as above with the relative location of scripting.js.

const testTrigger = require('<%= TEST_TRIGGER_MODULE %>');

const getSessionKey = (z, bundle) => {
const scripting = require('../scripting');
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same comment as above with the relative location of scripting.js.

};
<% if (hasGetConnectionLabelScripting) { %>
const getConnectionLabel = (z, bundle) => {
const scripting = require('../scripting');
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same comment as above with the relative location of scripting.js.

},
<% if (hasGetConnectionLabelScripting) { %>
connectionLabel: getConnectionLabel,
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same comment as above with the trailing comma removal for consistency.

],
sessionConfig: {
perform: getSessionKey
},
<% if (hasGetConnectionLabelScripting) { %>
connectionLabel: getConnectionLabel,
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same comment as above with the trailing comma removal for consistency.

"auth_data": {},
"auth_label": "",
"auth_mapping": {},
"auth_type": "Unknown Auth",
Copy link
Contributor

@BrunoBernardino BrunoBernardino Nov 17, 2017

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think we should try to render a custom auth for Unknown Auth. No Auth would be No Auth Needed.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I made an app https://zapier.com/developer/builder/app/79939/development and specified "No Auth" for the authentication. The dumped result (https://zapier.com/api/developer/v1/apps/79939/dump) is "auth_type": "Unknown Auth". Am I missing something here?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Well, in that case let it be, then!

@@ -87,6 +87,10 @@ const getAuthType = (definition) => {
return authTypeMap[definition.general.auth_type];
};

const hasAuth = (definition) => {
Copy link
Contributor

@BrunoBernardino BrunoBernardino Nov 17, 2017

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could this be moved to the getAuthMetaData as a returned property instead of its own function?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

They are separate functions because in some situations we only need to quickly check if the app needs authentication or not. I don't want to do all the unnecessary things in getAuthMetaData for those situations. Makes sense?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Alright!

Copy link
Contributor

@BrunoBernardino BrunoBernardino left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Just found one place missing the replacement from ../scripting to ./scripting and then I'll pull this down and test it around.

};
<% } else if (hasPreOAuthTokenScripting && !hasPostOAuthTokenScripting) { %>
const getAccessToken = (z, bundle) => {
const scripting = require('../scripting');
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I believe this one still needs to be changed?

@eliangcs
Copy link
Member Author

@BrunoBernardino Good catch! Fixed in fecf3c0.

@BrunoBernardino
Copy link
Contributor

BrunoBernardino commented Nov 28, 2017

Alright! I added a new app to the convert test (let me know if you want any help or pointers on doing that for new convert work that gets added), and all looks great:

Individually converting the app and running npm install and zapier test:

Running test suite.


  Creates - Recipe
    ✓ should create an object (1442ms)

  Searches - Recipe
    ✓ should get an object (391ms)

  Triggers - Recipe
    ✓ should get an array (307ms)


  3 passing (2s)

And running npm run test-convert:

simple-basic-auth converted successfully
simple-oauth converted successfully
trigger-session-auth converted successfully
apps converted successfully

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

2 participants