[APPS] Add OAuth auth for Apps#393
Conversation
🎉 All green!🧪 All tests passed 🔗 Commit SHA: 4cfb545 | Docs | Datadog PR Page | Give us feedback! |
53ad0e4 to
490c3f3
Compare
yoannmoinet
left a comment
There was a problem hiding this comment.
Doing a quick review first, to tackle my biggest comments 😃
| "dependencies": { | ||
| "@datadog/js-instrumentation-wasm": "1.0.8", | ||
| "@jridgewell/remapping": "2.3.5", | ||
| "@napi-rs/keyring": "1.3.0", |
There was a problem hiding this comment.
If these are in the core package do we need these as dependencies within all the build specific plugins (esbuild-plugin, rollup-plugin, etc)
There was a problem hiding this comment.
Yeah, I think we still need them here. The published packages bundle the internal @dd/* packages rather than depending on @dd/core at runtime, and the integrity dependency sync flattens external deps from internal workspaces into each published package. Since the OAuth helper in core dynamically loads oauth4webapi and @napi-rs/keyring, the published packages need to declare them so they’re installed for consumers.
There was a problem hiding this comment.
This is pretty bad.
We need to find a way to make this optional only.
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 703d88302a
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
| const OAUTH_PACKAGE_NAME = 'oauth4webapi'; | ||
| const KEYRING_PACKAGE_NAME = '@napi-rs/keyring'; | ||
|
|
||
| type OAuthAuthorizationServer = import('oauth4webapi').AuthorizationServer; | ||
| type OAuthClient = import('oauth4webapi').Client; | ||
| type OAuthModule = typeof import('oauth4webapi'); | ||
| type OAuthTokenEndpointResponse = import('oauth4webapi').TokenEndpointResponse; | ||
| type KeyringModule = typeof import('@napi-rs/keyring'); | ||
|
|
||
| // Load through a variable specifier so bundlers leave these as runtime requires | ||
| // instead of inlining them — notably the native `@napi-rs/keyring` binary. Node | ||
| // caches modules by specifier, so repeated calls reuse the same instance. | ||
| const loadOauth = () => import(OAUTH_PACKAGE_NAME) as Promise<OAuthModule>; | ||
| const loadKeyring = () => import(KEYRING_PACKAGE_NAME) as Promise<KeyringModule>; |
There was a problem hiding this comment.
Why do we do this if the dependency is required in all the package.json?
| return { errors, warnings }; | ||
| } | ||
|
|
||
| if (!requestAuth) { |
There was a problem hiding this comment.
Shouldn't this be reflected on the type instead?
| auth?: { | ||
| apiKey?: string; | ||
| appKey?: string; | ||
| site?: string; | ||
| } | ||
|
|
There was a problem hiding this comment.
This will break the root README once included in it.
Because we copy this ## Configuration block into the global configuration block of the root.
|
|
||
| > default: `apiKey` | ||
|
|
||
| Authentication method for uploading app bundles. Scoped to the `apps` plugin rather than the shared `auth` config, because not every Datadog endpoint supports OAuth. |
There was a problem hiding this comment.
Not sure this is a necessary detail...
| Authentication method for uploading app bundles. Scoped to the `apps` plugin rather than the shared `auth` config, because not every Datadog endpoint supports OAuth. | |
| Authentication method for uploading app bundles. |
| const { AsyncEntry } = await loadKeyring(); | ||
| return new AsyncEntry(OAUTH_KEYCHAIN_SERVICE, getOAuthCredentialAccount(site, options)); |
There was a problem hiding this comment.
What is keyring necessary for?
No alternative?
| "dependencies": { | ||
| "@datadog/js-instrumentation-wasm": "1.0.8", | ||
| "@jridgewell/remapping": "2.3.5", | ||
| "@napi-rs/keyring": "1.3.0", |
There was a problem hiding this comment.
This is pretty bad.
We need to find a way to make this optional only.
| return { errors, dependencies }; | ||
| }; | ||
|
|
||
| type DependencyType = 'dependencies' | 'optionalDependencies'; |
There was a problem hiding this comment.
Would it be worth separating out optionalDependencies integrity support into a separate PR?
b2ac87c to
2cc5df7
Compare
bdeb952 to
fb3a06d
Compare
| viteBuild: typeof build, | ||
| getBackendFunctions: () => BackendFunction[], | ||
| auth: AuthOptionsWithDefaults, | ||
| authMethod: AuthMethod, |
There was a problem hiding this comment.
Couldn't we just thread through doAuthenticatedRequest like we do in other places?
| : getAuthenticatedRequest(options.authOverrides.method, auth, log)) || | ||
| doMissingAuthenticationRequest; |
There was a problem hiding this comment.
I wonder if getAuthenticatedRequest should just throw if we are missing auth information. We probably need to differentiate between a 500 and 400 error in some cases, perhaps we should create error classes.
2e23fc6 to
e467ffc
Compare
| func: BackendFunction, | ||
| args: unknown[], | ||
| auth: AuthConfig, | ||
| site: Site, |
There was a problem hiding this comment.
It looks like we missed some places. We were support to revert site: Site, changes back to auth: AuthConfig,
e467ffc to
4cfb545
Compare
Summary
Depends on #421.
Adds OAuth support for Datadog Apps while keeping the optional dependency integrity support in its own PR:
oauth-request.ts, which owns OAuth token resolution anddoOAuthRequestdoRequestto accept request-ready auth via API/app keys or an already resolved OAuth access tokenapps.authOverrides.methodandDD_APPS_AUTH_METHOD/DATADOG_APPS_AUTH_METHOD, defaulting to API-key authoauth4webapias a regular dependency and@napi-rs/keyringas an optional dependencyValidation
yarn workspace @dd/tests test:unit packages/core/src/helpers/request.test.ts packages/core/src/helpers/oauth-request.test.ts packages/plugins/error-tracking/src/sourcemaps/sender.test.ts packages/plugins/apps/src/auth.test.ts packages/plugins/apps/src/upload.test.ts packages/plugins/apps/src/index.test.ts packages/plugins/apps/src/validate.test.ts packages/plugins/apps/src/vite/dev-server.test.ts packages/plugins/apps/src/vite/index.test.tsyarn cli integritygit diff --check