diff --git a/console-webapp/package-lock.json b/console-webapp/package-lock.json index 5b0bec4b47b..afdbc88ff9a 100644 --- a/console-webapp/package-lock.json +++ b/console-webapp/package-lock.json @@ -628,6 +628,18 @@ } } }, + "node_modules/@angular/build/node_modules/@types/node": { + "version": "25.7.0", + "resolved": "https://us-npm.pkg.dev/artifact-foundry-prod/ah-3p-staging-npm/@types/node/-/node-25.7.0.tgz", + "integrity": "sha512-z+pdZyxE+RTQE9AcboAZCb4otwcrvgHD+GlBpPgn0emDVt0ohrTMhAwlr2Wd9nZ+nihhYFxO2pThz3C5qSu2Eg==", + "dev": true, + "license": "MIT", + "optional": true, + "peer": true, + "dependencies": { + "undici-types": "~7.21.0" + } + }, "node_modules/@angular/build/node_modules/@vitejs/plugin-basic-ssl": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/@vitejs/plugin-basic-ssl/-/plugin-basic-ssl-2.1.0.tgz", @@ -641,6 +653,24 @@ "vite": "^6.0.0 || ^7.0.0" } }, + "node_modules/@angular/build/node_modules/chokidar": { + "version": "5.0.0", + "resolved": "https://us-npm.pkg.dev/artifact-foundry-prod/ah-3p-staging-npm/chokidar/-/chokidar-5.0.0.tgz", + "integrity": "sha512-TQMmc3w+5AxjpL8iIiwebF73dRDF4fBIieAqGn9RGCWaEVwQ6Fb2cGe31Yns0RRIzii5goJ1Y7xbMwo1TxMplw==", + "dev": true, + "license": "MIT", + "optional": true, + "peer": true, + "dependencies": { + "readdirp": "^5.0.0" + }, + "engines": { + "node": ">= 20.19.0" + }, + "funding": { + "url": "https://paulmillr.com/funding/" + } + }, "node_modules/@angular/build/node_modules/magic-string": { "version": "0.30.21", "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.30.21.tgz", @@ -664,6 +694,22 @@ "url": "https://github.com/sponsors/jonschlinkert" } }, + "node_modules/@angular/build/node_modules/readdirp": { + "version": "5.0.0", + "resolved": "https://us-npm.pkg.dev/artifact-foundry-prod/ah-3p-staging-npm/readdirp/-/readdirp-5.0.0.tgz", + "integrity": "sha512-9u/XQ1pvrQtYyMpZe7DXKv2p5CNvyVwzUB6uhLAnQwHMSgKMBR62lc7AHljaeteeHXn11XTAaLLUVZYVZyuRBQ==", + "dev": true, + "license": "MIT", + "optional": true, + "peer": true, + "engines": { + "node": ">= 20.19.0" + }, + "funding": { + "type": "individual", + "url": "https://paulmillr.com/funding/" + } + }, "node_modules/@angular/build/node_modules/rxjs": { "version": "7.8.2", "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-7.8.2.tgz", @@ -697,6 +743,15 @@ "node": ">= 12" } }, + "node_modules/@angular/build/node_modules/undici-types": { + "version": "7.21.0", + "resolved": "https://us-npm.pkg.dev/artifact-foundry-prod/ah-3p-staging-npm/undici-types/-/undici-types-7.21.0.tgz", + "integrity": "sha512-w9IMgQrz4O0YN1LtB7K5P63vhlIOvC7opSmouCJ+ZywlPAlO9gIkJ+otk6LvGpAs2wg4econaCz3TvQ9xPoyuQ==", + "dev": true, + "license": "MIT", + "optional": true, + "peer": true + }, "node_modules/@angular/build/node_modules/vite": { "version": "7.3.0", "resolved": "https://registry.npmjs.org/vite/-/vite-7.3.0.tgz", @@ -916,6 +971,24 @@ "url": "https://github.com/chalk/chalk?sponsor=1" } }, + "node_modules/@angular/cli/node_modules/chokidar": { + "version": "5.0.0", + "resolved": "https://us-npm.pkg.dev/artifact-foundry-prod/ah-3p-staging-npm/chokidar/-/chokidar-5.0.0.tgz", + "integrity": "sha512-TQMmc3w+5AxjpL8iIiwebF73dRDF4fBIieAqGn9RGCWaEVwQ6Fb2cGe31Yns0RRIzii5goJ1Y7xbMwo1TxMplw==", + "dev": true, + "license": "MIT", + "optional": true, + "peer": true, + "dependencies": { + "readdirp": "^5.0.0" + }, + "engines": { + "node": ">= 20.19.0" + }, + "funding": { + "url": "https://paulmillr.com/funding/" + } + }, "node_modules/@angular/cli/node_modules/cli-spinners": { "version": "3.4.0", "resolved": "https://registry.npmjs.org/cli-spinners/-/cli-spinners-3.4.0.tgz", @@ -1019,6 +1092,22 @@ "url": "https://github.com/sponsors/jonschlinkert" } }, + "node_modules/@angular/cli/node_modules/readdirp": { + "version": "5.0.0", + "resolved": "https://us-npm.pkg.dev/artifact-foundry-prod/ah-3p-staging-npm/readdirp/-/readdirp-5.0.0.tgz", + "integrity": "sha512-9u/XQ1pvrQtYyMpZe7DXKv2p5CNvyVwzUB6uhLAnQwHMSgKMBR62lc7AHljaeteeHXn11XTAaLLUVZYVZyuRBQ==", + "dev": true, + "license": "MIT", + "optional": true, + "peer": true, + "engines": { + "node": ">= 20.19.0" + }, + "funding": { + "type": "individual", + "url": "https://paulmillr.com/funding/" + } + }, "node_modules/@angular/cli/node_modules/rxjs": { "version": "7.8.2", "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-7.8.2.tgz", @@ -4606,6 +4695,24 @@ "url": "https://github.com/chalk/chalk?sponsor=1" } }, + "node_modules/@schematics/angular/node_modules/chokidar": { + "version": "5.0.0", + "resolved": "https://us-npm.pkg.dev/artifact-foundry-prod/ah-3p-staging-npm/chokidar/-/chokidar-5.0.0.tgz", + "integrity": "sha512-TQMmc3w+5AxjpL8iIiwebF73dRDF4fBIieAqGn9RGCWaEVwQ6Fb2cGe31Yns0RRIzii5goJ1Y7xbMwo1TxMplw==", + "dev": true, + "license": "MIT", + "optional": true, + "peer": true, + "dependencies": { + "readdirp": "^5.0.0" + }, + "engines": { + "node": ">= 20.19.0" + }, + "funding": { + "url": "https://paulmillr.com/funding/" + } + }, "node_modules/@schematics/angular/node_modules/cli-spinners": { "version": "3.4.0", "resolved": "https://registry.npmjs.org/cli-spinners/-/cli-spinners-3.4.0.tgz", @@ -4709,6 +4816,22 @@ "url": "https://github.com/sponsors/jonschlinkert" } }, + "node_modules/@schematics/angular/node_modules/readdirp": { + "version": "5.0.0", + "resolved": "https://us-npm.pkg.dev/artifact-foundry-prod/ah-3p-staging-npm/readdirp/-/readdirp-5.0.0.tgz", + "integrity": "sha512-9u/XQ1pvrQtYyMpZe7DXKv2p5CNvyVwzUB6uhLAnQwHMSgKMBR62lc7AHljaeteeHXn11XTAaLLUVZYVZyuRBQ==", + "dev": true, + "license": "MIT", + "optional": true, + "peer": true, + "engines": { + "node": ">= 20.19.0" + }, + "funding": { + "type": "individual", + "url": "https://paulmillr.com/funding/" + } + }, "node_modules/@schematics/angular/node_modules/rxjs": { "version": "7.8.2", "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-7.8.2.tgz", diff --git a/core/src/main/java/google/registry/batch/BatchModule.java b/core/src/main/java/google/registry/batch/BatchModule.java index e4b9c6a4842..b2854c2fabf 100644 --- a/core/src/main/java/google/registry/batch/BatchModule.java +++ b/core/src/main/java/google/registry/batch/BatchModule.java @@ -54,9 +54,15 @@ public class BatchModule { static final int DEFAULT_MAX_QPS = 10; @Provides - @Parameter("url") - static String provideUrl(HttpServletRequest req) { - return extractRequiredParameter(req, "url"); + @Parameter("sender") + static String provideSender(HttpServletRequest req) { + return extractRequiredParameter(req, "sender"); + } + + @Provides + @Parameter("receiver") + static String provideReceiver(HttpServletRequest req) { + return extractRequiredParameter(req, "receiver"); } @Provides diff --git a/core/src/main/java/google/registry/batch/CannedScriptExecutionAction.java b/core/src/main/java/google/registry/batch/CannedScriptExecutionAction.java index ca68a2f7fb3..a83e4899796 100644 --- a/core/src/main/java/google/registry/batch/CannedScriptExecutionAction.java +++ b/core/src/main/java/google/registry/batch/CannedScriptExecutionAction.java @@ -16,30 +16,32 @@ import static google.registry.request.Action.Method.GET; import static google.registry.request.Action.Method.POST; -import static java.nio.charset.StandardCharsets.UTF_8; +import com.google.api.services.gmail.Gmail; import com.google.common.flogger.FluentLogger; +import dagger.Lazy; +import google.registry.config.RegistryConfig.Config; +import google.registry.groups.GmailClient; import google.registry.request.Action; import google.registry.request.Parameter; import google.registry.request.Response; -import google.registry.request.UrlConnectionService; -import google.registry.request.UrlConnectionUtils; import google.registry.request.auth.Auth; +import google.registry.util.EmailMessage; +import google.registry.util.Retrier; import jakarta.inject.Inject; -import java.net.URL; -import javax.net.ssl.HttpsURLConnection; +import jakarta.mail.internet.AddressException; +import jakarta.mail.internet.InternetAddress; /** * Action that executes a canned script specified by the caller. * *
This class provides a hook for invoking hard-coded methods. The main use case is to verify in * Sandbox and Production environments new features that depend on environment-specific - * configurations. For example, the {@code DelegatedCredential}, which requires correct GWorkspace - * configuration, has been tested this way. Since it is a hassle to add or remove endpoints, we keep - * this class all the time. + * configurations. * *
This action can be invoked using the Nomulus CLI command: {@code nomulus -e ${env} curl
- * --service BACKEND -X POST -u '/_dr/task/executeCannedScript}'}
+ * --service BACKEND -X POST -d 'sender=sender@example.com' -d 'receiver=receiver@example.com' -u
+ * '/_dr/task/executeCannedScript'}
*/
@Action(
service = Action.Service.BACKEND,
@@ -50,39 +52,50 @@
public class CannedScriptExecutionAction implements Runnable {
private static final FluentLogger logger = FluentLogger.forEnclosingClass();
- @Inject UrlConnectionService urlConnectionService;
+ @Inject Lazy