feat: email notification (#26692)
update email sending flow for inviting users to workspace and forgot password with new templates fixes: https://github.com/appsmithorg/appsmith/issues/19462 code changes: **new code** * introduces new EmailService **refactoring** * moves all email sending flows to the new email service * moves all email constants and templates to the Email constants **code deleted** * removed code for welcome email invite
This commit is contained in:
parent
9b46e7e127
commit
feaf5eea03
|
|
@ -214,10 +214,9 @@ public class AuthenticationSuccessHandlerCE implements ServerAuthenticationSucce
|
|||
.flatMap(defaultApplication -> postVerificationRequiredHandler(
|
||||
webFilterExchange, user, defaultApplication, TRUE));
|
||||
} else {
|
||||
return Mono.zip(
|
||||
userService.sendWelcomeEmail(user, originHeader),
|
||||
createDefaultApplication(defaultWorkspaceId, authentication))
|
||||
.flatMap(obj -> redirectHelper.handleRedirect(webFilterExchange, obj.getT2(), true));
|
||||
return createDefaultApplication(defaultWorkspaceId, authentication)
|
||||
.flatMap(application ->
|
||||
redirectHelper.handleRedirect(webFilterExchange, application, true));
|
||||
}
|
||||
});
|
||||
} else {
|
||||
|
|
@ -226,9 +225,7 @@ public class AuthenticationSuccessHandlerCE implements ServerAuthenticationSucce
|
|||
if (TRUE.equals(isVerificationRequired)) {
|
||||
return postVerificationRequiredHandler(webFilterExchange, user, null, TRUE);
|
||||
} else {
|
||||
return userService
|
||||
.sendWelcomeEmail(user, originHeader)
|
||||
.then(redirectHelper.handleRedirect(webFilterExchange, null, true));
|
||||
return redirectHelper.handleRedirect(webFilterExchange, null, true);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
|
@ -289,17 +286,12 @@ public class AuthenticationSuccessHandlerCE implements ServerAuthenticationSucce
|
|||
redirectionMono = workspaceService
|
||||
.isCreateWorkspaceAllowed(TRUE)
|
||||
.flatMap(isCreateWorkspaceAllowed -> {
|
||||
if (isCreateWorkspaceAllowed) {
|
||||
|
||||
return Mono.zip(
|
||||
userService.sendWelcomeEmail(user, originHeader),
|
||||
createDefaultApplication(defaultWorkspaceId, authentication))
|
||||
.flatMap(objects -> handleOAuth2Redirect(
|
||||
webFilterExchange, objects.getT2(), finalIsFromSignup));
|
||||
if (isCreateWorkspaceAllowed.equals(Boolean.TRUE)) {
|
||||
return createDefaultApplication(defaultWorkspaceId, authentication)
|
||||
.flatMap(application -> handleOAuth2Redirect(
|
||||
webFilterExchange, application, finalIsFromSignup));
|
||||
}
|
||||
return userService
|
||||
.sendWelcomeEmail(user, originHeader)
|
||||
.then(handleOAuth2Redirect(webFilterExchange, null, finalIsFromSignup));
|
||||
return handleOAuth2Redirect(webFilterExchange, null, finalIsFromSignup);
|
||||
});
|
||||
} else {
|
||||
redirectionMono = handleOAuth2Redirect(webFilterExchange, null, isFromSignup);
|
||||
|
|
|
|||
|
|
@ -0,0 +1,32 @@
|
|||
package com.appsmith.server.constants.ce;
|
||||
|
||||
import com.appsmith.server.constants.FieldName;
|
||||
|
||||
public class EmailConstantsCE {
|
||||
public static final String INSTANCE_NAME = "instanceName";
|
||||
public static final String RESET_URL = "resetUrl";
|
||||
public static final String EMAIL_ROLE_ADMINISTRATOR_TEXT = "an " + FieldName.ADMINISTRATOR.toLowerCase();
|
||||
public static final String EMAIL_ROLE_DEVELOPER_TEXT = "a " + FieldName.DEVELOPER.toLowerCase();
|
||||
public static final String EMAIL_ROLE_VIEWER_TEXT = "an " + FieldName.VIEWER.toLowerCase();
|
||||
public static final String PRIMARY_LINK_URL = "primaryLinkUrl";
|
||||
public static final String PRIMARY_LINK_TEXT = "primaryLinkText";
|
||||
public static final String PRIMARY_LINK_TEXT_USER_SIGNUP = "Sign up now";
|
||||
public static final String PRIMARY_LINK_TEXT_INVITE_TO_INSTANCE = "Go to instance";
|
||||
public static final String PRIMARY_LINK_TEXT_WORKSPACE_REDIRECTION = "Go to your Appsmith workspace";
|
||||
|
||||
public static final String INVITE_USER_CLIENT_URL_FORMAT = "%s/user/signup?email=%s";
|
||||
public static final String WORKSPACE_EMAIL_SUBJECT_FOR_NEW_USER = "You’re invited to the workspace %s.";
|
||||
public static final String FORGOT_PASSWORD_EMAIL_SUBJECT = "Reset your Appsmith password";
|
||||
public static final String EMAIL_VERIFICATION_EMAIL_SUBJECT = "Verify your account";
|
||||
public static final String INSTANCE_ADMIN_INVITE_EMAIL_SUBJECT = "You're invited to an Appsmith instance";
|
||||
public static final String INVITE_WORKSPACE_TEMPLATE_EXISTING_USER_CE =
|
||||
"email/ce/inviteWorkspaceExistingUserTemplate.html";
|
||||
public static final String INVITE_WORKSPACE_TEMPLATE_NEW_USER_CE = "email/ce/inviteWorkspaceNewUserTemplate.html";
|
||||
public static final String FORGOT_PASSWORD_TEMPLATE_CE = "email/ce/forgotPasswordTemplate.html";
|
||||
public static final String INSTANCE_ADMIN_INVITE_EMAIL_TEMPLATE = "email/ce/instanceAdminInviteTemplate.html";
|
||||
public static final String EMAIL_VERIFICATION_EMAIL_TEMPLATE = "email/emailVerificationTemplate.html";
|
||||
public static final String WORKSPACE_URL = "%s/applications#%s";
|
||||
public static final String INVITER_FIRST_NAME = "inviterFirstName";
|
||||
public static final String INVITER_WORKSPACE_NAME = "inviterWorkspaceName";
|
||||
public static final String EMAIL_VERIFICATION_URL = "verificationUrl";
|
||||
}
|
||||
|
|
@ -15,6 +15,7 @@ import org.springframework.web.bind.annotation.GetMapping;
|
|||
import org.springframework.web.bind.annotation.PostMapping;
|
||||
import org.springframework.web.bind.annotation.PutMapping;
|
||||
import org.springframework.web.bind.annotation.RequestBody;
|
||||
import org.springframework.web.bind.annotation.RequestHeader;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.server.ServerWebExchange;
|
||||
import reactor.core.publisher.Mono;
|
||||
|
|
@ -47,19 +48,23 @@ public class InstanceAdminControllerCE {
|
|||
@PutMapping(
|
||||
value = "/env",
|
||||
consumes = {MediaType.APPLICATION_JSON_VALUE})
|
||||
public Mono<ResponseDTO<Void>> saveEnvChangesJSON(@Valid @RequestBody Map<String, String> changes) {
|
||||
public Mono<ResponseDTO<Void>> saveEnvChangesJSON(
|
||||
@Valid @RequestBody Map<String, String> changes, @RequestHeader("Origin") String originHeader) {
|
||||
log.debug("Applying env updates {}", changes.keySet());
|
||||
return envManager.applyChanges(changes).thenReturn(new ResponseDTO<>(HttpStatus.OK.value(), null, null));
|
||||
return envManager
|
||||
.applyChanges(changes, originHeader)
|
||||
.thenReturn(new ResponseDTO<>(HttpStatus.OK.value(), null, null));
|
||||
}
|
||||
|
||||
@JsonView(Views.Public.class)
|
||||
@PutMapping(
|
||||
value = "/env",
|
||||
consumes = {MediaType.MULTIPART_FORM_DATA_VALUE})
|
||||
public Mono<ResponseDTO<Void>> saveEnvChangesMultipartFormData(ServerWebExchange exchange) {
|
||||
public Mono<ResponseDTO<Void>> saveEnvChangesMultipartFormData(
|
||||
@RequestHeader("Origin") String originHeader, ServerWebExchange exchange) {
|
||||
log.debug("Applying env updates from form data");
|
||||
return exchange.getMultipartData()
|
||||
.flatMap(envManager::applyChangesFromMultipartFormData)
|
||||
.flatMap(formData -> envManager.applyChangesFromMultipartFormData(formData, originHeader))
|
||||
.thenReturn(new ResponseDTO<>(HttpStatus.OK.value(), null, null));
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -91,9 +91,11 @@ public class UserControllerCE extends BaseController<UserService, User, String>
|
|||
value = "/super",
|
||||
consumes = {MediaType.APPLICATION_JSON_VALUE})
|
||||
public Mono<ResponseDTO<User>> createSuperUser(
|
||||
@Valid @RequestBody UserSignupRequestDTO resource, ServerWebExchange exchange) {
|
||||
@Valid @RequestBody UserSignupRequestDTO resource,
|
||||
@RequestHeader("Origin") String originHeader,
|
||||
ServerWebExchange exchange) {
|
||||
return userSignup
|
||||
.signupAndLoginSuper(resource, exchange)
|
||||
.signupAndLoginSuper(resource, originHeader, exchange)
|
||||
.map(created -> new ResponseDTO<>(HttpStatus.CREATED.value(), created, null));
|
||||
}
|
||||
|
||||
|
|
@ -101,8 +103,9 @@ public class UserControllerCE extends BaseController<UserService, User, String>
|
|||
@PostMapping(
|
||||
value = "/super",
|
||||
consumes = {MediaType.APPLICATION_FORM_URLENCODED_VALUE})
|
||||
public Mono<Void> createSuperUserFromFormData(ServerWebExchange exchange) {
|
||||
return userSignup.signupAndLoginSuperFromFormData(exchange);
|
||||
public Mono<Void> createSuperUserFromFormData(
|
||||
@RequestHeader("Origin") String originHeader, ServerWebExchange exchange) {
|
||||
return userSignup.signupAndLoginSuperFromFormData(originHeader, exchange);
|
||||
}
|
||||
|
||||
@JsonView(Views.Public.class)
|
||||
|
|
|
|||
|
|
@ -0,0 +1,5 @@
|
|||
package com.appsmith.server.services;
|
||||
|
||||
import com.appsmith.server.services.ce.EmailServiceCE;
|
||||
|
||||
public interface EmailService extends EmailServiceCE {}
|
||||
|
|
@ -0,0 +1,12 @@
|
|||
package com.appsmith.server.services;
|
||||
|
||||
import com.appsmith.server.notifications.EmailSender;
|
||||
import com.appsmith.server.services.ce.EmailServiceCEImpl;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
@Service
|
||||
public class EmailServiceImpl extends EmailServiceCEImpl implements EmailService {
|
||||
public EmailServiceImpl(EmailSender emailSender, TenantService tenantService) {
|
||||
super(emailSender, tenantService);
|
||||
}
|
||||
}
|
||||
|
|
@ -3,7 +3,6 @@ package com.appsmith.server.services;
|
|||
import com.appsmith.external.services.EncryptionService;
|
||||
import com.appsmith.server.configurations.CommonConfig;
|
||||
import com.appsmith.server.configurations.EmailConfig;
|
||||
import com.appsmith.server.helpers.RedirectHelper;
|
||||
import com.appsmith.server.helpers.UserUtils;
|
||||
import com.appsmith.server.notifications.EmailSender;
|
||||
import com.appsmith.server.ratelimiting.RateLimitService;
|
||||
|
|
@ -49,7 +48,7 @@ public class UserServiceImpl extends UserServiceCECompatibleImpl implements User
|
|||
PermissionGroupService permissionGroupService,
|
||||
UserUtils userUtils,
|
||||
EmailVerificationTokenRepository emailVerificationTokenRepository,
|
||||
RedirectHelper redirectHelper,
|
||||
EmailService emailService,
|
||||
RateLimitService rateLimitService) {
|
||||
super(
|
||||
scheduler,
|
||||
|
|
@ -74,7 +73,7 @@ public class UserServiceImpl extends UserServiceCECompatibleImpl implements User
|
|||
permissionGroupService,
|
||||
userUtils,
|
||||
emailVerificationTokenRepository,
|
||||
redirectHelper,
|
||||
emailService,
|
||||
rateLimitService);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,23 @@
|
|||
package com.appsmith.server.services.ce;
|
||||
|
||||
import com.appsmith.server.domains.PermissionGroup;
|
||||
import com.appsmith.server.domains.User;
|
||||
import com.appsmith.server.domains.Workspace;
|
||||
import reactor.core.publisher.Mono;
|
||||
|
||||
public interface EmailServiceCE {
|
||||
Mono<Boolean> sendForgotPasswordEmail(String email, String resetUrl, String originHeader);
|
||||
|
||||
Mono<Boolean> sendInviteUserToWorkspaceEmail(
|
||||
User invitingUser,
|
||||
User invitedUser,
|
||||
Workspace workspaceInvitedTo,
|
||||
PermissionGroup assignedPermissionGroup,
|
||||
String originHeader,
|
||||
boolean isNewUser);
|
||||
|
||||
Mono<Boolean> sendEmailVerificationEmail(User user, String verificationUrl);
|
||||
|
||||
Mono<Boolean> sendInstanceAdminInviteEmail(
|
||||
User invitedUser, User invitingUser, String originHeader, boolean isNewUser);
|
||||
}
|
||||
|
|
@ -0,0 +1,159 @@
|
|||
package com.appsmith.server.services.ce;
|
||||
|
||||
import com.appsmith.server.constants.FieldName;
|
||||
import com.appsmith.server.domains.PermissionGroup;
|
||||
import com.appsmith.server.domains.TenantConfiguration;
|
||||
import com.appsmith.server.domains.User;
|
||||
import com.appsmith.server.domains.Workspace;
|
||||
import com.appsmith.server.notifications.EmailSender;
|
||||
import com.appsmith.server.services.TenantService;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import reactor.core.publisher.Mono;
|
||||
|
||||
import java.net.URLEncoder;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
import static com.appsmith.server.constants.ce.EmailConstantsCE.*;
|
||||
|
||||
public class EmailServiceCEImpl implements EmailServiceCE {
|
||||
private final EmailSender emailSender;
|
||||
private final TenantService tenantService;
|
||||
|
||||
public EmailServiceCEImpl(EmailSender emailSender, TenantService tenantService) {
|
||||
this.emailSender = emailSender;
|
||||
this.tenantService = tenantService;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Mono<Boolean> sendForgotPasswordEmail(String email, String resetUrl, String originHeader) {
|
||||
Map<String, String> params = new HashMap<>();
|
||||
params.put(RESET_URL, resetUrl);
|
||||
return this.enrichParams(params)
|
||||
.flatMap(enrichedParams -> this.enrichWithBrandParams(enrichedParams, originHeader)
|
||||
.flatMap(updatedParams -> emailSender.sendMail(
|
||||
email,
|
||||
String.format(FORGOT_PASSWORD_EMAIL_SUBJECT, updatedParams.get(INSTANCE_NAME)),
|
||||
getForgotPasswordTemplate(),
|
||||
updatedParams)));
|
||||
}
|
||||
|
||||
@Override
|
||||
public Mono<Boolean> sendInviteUserToWorkspaceEmail(
|
||||
User invitingUser,
|
||||
User invitedUser,
|
||||
Workspace workspaceInvitedTo,
|
||||
PermissionGroup assignedPermissionGroup,
|
||||
String originHeader,
|
||||
boolean isNewUser) {
|
||||
String inviteUrl = isNewUser
|
||||
? String.format(
|
||||
INVITE_USER_CLIENT_URL_FORMAT,
|
||||
originHeader,
|
||||
URLEncoder.encode(invitedUser.getUsername().toLowerCase(), StandardCharsets.UTF_8))
|
||||
: originHeader;
|
||||
String emailSubject = String.format(WORKSPACE_EMAIL_SUBJECT_FOR_NEW_USER, workspaceInvitedTo.getName());
|
||||
Map<String, String> params = getInviteToWorkspaceEmailParams(
|
||||
workspaceInvitedTo, invitingUser, inviteUrl, assignedPermissionGroup.getName(), isNewUser);
|
||||
return this.enrichParams(params).flatMap(enrichedParams -> this.enrichWithBrandParams(
|
||||
enrichedParams, originHeader)
|
||||
.flatMap(updatedParams -> emailSender.sendMail(
|
||||
invitedUser.getEmail(), emailSubject, getWorkspaceInviteTemplate(isNewUser), updatedParams)));
|
||||
}
|
||||
|
||||
@Override
|
||||
public Mono<Boolean> sendEmailVerificationEmail(User user, String verificationURL) {
|
||||
Map<String, String> params = new HashMap<>();
|
||||
params.put(EMAIL_VERIFICATION_URL, verificationURL);
|
||||
return this.enrichParams(params)
|
||||
.flatMap(updatedParams -> emailSender.sendMail(
|
||||
user.getEmail(),
|
||||
EMAIL_VERIFICATION_EMAIL_SUBJECT,
|
||||
EMAIL_VERIFICATION_EMAIL_TEMPLATE,
|
||||
updatedParams));
|
||||
}
|
||||
|
||||
@Override
|
||||
public Mono<Boolean> sendInstanceAdminInviteEmail(
|
||||
User invitedUser, User invitingUser, String originHeader, boolean isNewUser) {
|
||||
Map<String, String> params = new HashMap<>();
|
||||
String inviteUrl = isNewUser
|
||||
? String.format(
|
||||
INVITE_USER_CLIENT_URL_FORMAT,
|
||||
originHeader,
|
||||
URLEncoder.encode(invitedUser.getUsername().toLowerCase(), StandardCharsets.UTF_8))
|
||||
: originHeader;
|
||||
params.put(PRIMARY_LINK_URL, inviteUrl);
|
||||
|
||||
String primaryLinkText = isNewUser ? PRIMARY_LINK_TEXT_USER_SIGNUP : PRIMARY_LINK_TEXT_INVITE_TO_INSTANCE;
|
||||
params.put(PRIMARY_LINK_TEXT, primaryLinkText);
|
||||
|
||||
if (invitingUser != null) {
|
||||
params.put(INVITER_FIRST_NAME, StringUtils.defaultIfEmpty(invitingUser.getName(), invitingUser.getEmail()));
|
||||
}
|
||||
return this.enrichParams(params)
|
||||
.flatMap(enrichedParams -> this.enrichWithBrandParams(enrichedParams, originHeader))
|
||||
.flatMap(updatedParams -> emailSender.sendMail(
|
||||
invitedUser.getEmail(),
|
||||
String.format(INSTANCE_ADMIN_INVITE_EMAIL_SUBJECT),
|
||||
getAdminInstanceInviteTemplate(),
|
||||
updatedParams));
|
||||
}
|
||||
|
||||
protected Mono<Map<String, String>> enrichParams(Map<String, String> params) {
|
||||
return tenantService.getDefaultTenant().map(tenant -> {
|
||||
final TenantConfiguration tenantConfiguration = tenant.getTenantConfiguration();
|
||||
params.put(INSTANCE_NAME, StringUtils.defaultIfEmpty(tenantConfiguration.getInstanceName(), "Appsmith"));
|
||||
return params;
|
||||
});
|
||||
}
|
||||
|
||||
protected Mono<Map<String, String>> enrichWithBrandParams(Map<String, String> params, String origin) {
|
||||
return Mono.just(params);
|
||||
}
|
||||
|
||||
protected String getForgotPasswordTemplate() {
|
||||
return FORGOT_PASSWORD_TEMPLATE_CE;
|
||||
}
|
||||
|
||||
protected String getWorkspaceInviteTemplate(boolean isNewUser) {
|
||||
if (isNewUser) return INVITE_WORKSPACE_TEMPLATE_NEW_USER_CE;
|
||||
|
||||
return INVITE_WORKSPACE_TEMPLATE_EXISTING_USER_CE;
|
||||
}
|
||||
|
||||
protected String getAdminInstanceInviteTemplate() {
|
||||
return INSTANCE_ADMIN_INVITE_EMAIL_TEMPLATE;
|
||||
}
|
||||
|
||||
private Map<String, String> getInviteToWorkspaceEmailParams(
|
||||
Workspace workspace, User inviter, String inviteUrl, String roleType, boolean isNewUser) {
|
||||
Map<String, String> params = new HashMap<>();
|
||||
if (workspace != null) {
|
||||
params.put(INVITER_WORKSPACE_NAME, workspace.getName());
|
||||
}
|
||||
if (inviter != null) {
|
||||
params.put(INVITER_FIRST_NAME, StringUtils.defaultIfEmpty(inviter.getName(), inviter.getEmail()));
|
||||
}
|
||||
if (roleType != null) {
|
||||
if (roleType.startsWith(FieldName.ADMINISTRATOR)) {
|
||||
params.put(FieldName.ROLE, EMAIL_ROLE_ADMINISTRATOR_TEXT);
|
||||
} else if (roleType.startsWith(FieldName.DEVELOPER)) {
|
||||
params.put(FieldName.ROLE, EMAIL_ROLE_DEVELOPER_TEXT);
|
||||
} else if (roleType.startsWith(FieldName.VIEWER)) {
|
||||
params.put(FieldName.ROLE, EMAIL_ROLE_VIEWER_TEXT);
|
||||
}
|
||||
}
|
||||
if (isNewUser) {
|
||||
params.put(PRIMARY_LINK_URL, inviteUrl);
|
||||
params.put(PRIMARY_LINK_TEXT, PRIMARY_LINK_TEXT_USER_SIGNUP);
|
||||
} else {
|
||||
if (workspace != null) {
|
||||
params.put(PRIMARY_LINK_URL, String.format(WORKSPACE_URL, inviteUrl, workspace.getId()));
|
||||
}
|
||||
params.put(PRIMARY_LINK_TEXT, PRIMARY_LINK_TEXT_WORKSPACE_REDIRECTION);
|
||||
}
|
||||
return params;
|
||||
}
|
||||
}
|
||||
|
|
@ -2,7 +2,6 @@ package com.appsmith.server.services.ce;
|
|||
|
||||
import com.appsmith.server.acl.AclPermission;
|
||||
import com.appsmith.server.domains.User;
|
||||
import com.appsmith.server.domains.Workspace;
|
||||
import com.appsmith.server.dtos.ResendEmailVerificationDTO;
|
||||
import com.appsmith.server.dtos.ResetUserPasswordDTO;
|
||||
import com.appsmith.server.dtos.UserProfileDTO;
|
||||
|
|
@ -13,7 +12,6 @@ import org.springframework.web.server.ServerWebExchange;
|
|||
import reactor.core.publisher.Flux;
|
||||
import reactor.core.publisher.Mono;
|
||||
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
public interface UserServiceCE extends CrudService<User, String> {
|
||||
|
|
@ -30,29 +28,18 @@ public interface UserServiceCE extends CrudService<User, String> {
|
|||
|
||||
Mono<Boolean> resetPasswordAfterForgotPassword(String token, User user);
|
||||
|
||||
Mono<UserSignupDTO> createUser(User user, String originHeader);
|
||||
|
||||
Mono<UserSignupDTO> createUserAndSendEmail(User user, String originHeader);
|
||||
Mono<UserSignupDTO> createUser(User user);
|
||||
|
||||
Mono<User> userCreate(User user, boolean isAdminUser);
|
||||
|
||||
Mono<? extends User> createNewUserAndSendInviteEmail(
|
||||
String email, String originHeader, Workspace workspace, User inviter, String role);
|
||||
|
||||
Mono<User> updateCurrentUser(UserUpdateDTO updates, ServerWebExchange exchange);
|
||||
|
||||
Map<String, String> getEmailParams(Workspace workspace, User inviterUser, String inviteUrl, boolean isNewUser);
|
||||
|
||||
Mono<Boolean> isUsersEmpty();
|
||||
|
||||
Mono<UserProfileDTO> buildUserProfileDTO(User user);
|
||||
|
||||
Flux<User> getAllByEmails(Set<String> emails, AclPermission permission);
|
||||
|
||||
Mono<Map<String, String>> updateTenantLogoInParams(Map<String, String> params, String origin);
|
||||
|
||||
Mono<User> sendWelcomeEmail(User user, String originHeader);
|
||||
|
||||
Mono<User> updateWithoutPermission(String id, User update);
|
||||
|
||||
Mono<Boolean> resendEmailVerification(ResendEmailVerificationDTO resendEmailVerificationDTO, String redirectUrl);
|
||||
|
|
|
|||
|
|
@ -6,7 +6,6 @@ import com.appsmith.external.services.EncryptionService;
|
|||
import com.appsmith.server.acl.AclPermission;
|
||||
import com.appsmith.server.configurations.CommonConfig;
|
||||
import com.appsmith.server.configurations.EmailConfig;
|
||||
import com.appsmith.server.constants.Appsmith;
|
||||
import com.appsmith.server.constants.FieldName;
|
||||
import com.appsmith.server.constants.RateLimitConstants;
|
||||
import com.appsmith.server.domains.EmailVerificationToken;
|
||||
|
|
@ -27,7 +26,6 @@ import com.appsmith.server.dtos.UserSignupDTO;
|
|||
import com.appsmith.server.dtos.UserUpdateDTO;
|
||||
import com.appsmith.server.exceptions.AppsmithError;
|
||||
import com.appsmith.server.exceptions.AppsmithException;
|
||||
import com.appsmith.server.helpers.RedirectHelper;
|
||||
import com.appsmith.server.helpers.UserUtils;
|
||||
import com.appsmith.server.helpers.ValidationUtils;
|
||||
import com.appsmith.server.notifications.EmailSender;
|
||||
|
|
@ -38,6 +36,7 @@ import com.appsmith.server.repositories.PasswordResetTokenRepository;
|
|||
import com.appsmith.server.repositories.UserRepository;
|
||||
import com.appsmith.server.services.AnalyticsService;
|
||||
import com.appsmith.server.services.BaseService;
|
||||
import com.appsmith.server.services.EmailService;
|
||||
import com.appsmith.server.services.PermissionGroupService;
|
||||
import com.appsmith.server.services.SessionUserService;
|
||||
import com.appsmith.server.services.TenantService;
|
||||
|
|
@ -68,7 +67,6 @@ import org.springframework.util.StringUtils;
|
|||
import org.springframework.web.server.ServerWebExchange;
|
||||
import org.springframework.web.server.WebFilterChain;
|
||||
import org.springframework.web.server.WebSession;
|
||||
import reactor.core.Exceptions;
|
||||
import reactor.core.publisher.Flux;
|
||||
import reactor.core.publisher.Mono;
|
||||
import reactor.core.scheduler.Scheduler;
|
||||
|
|
@ -106,34 +104,26 @@ public class UserServiceCEImpl extends BaseService<UserRepository, User, String>
|
|||
private final PasswordResetTokenRepository passwordResetTokenRepository;
|
||||
|
||||
private final PasswordEncoder passwordEncoder;
|
||||
private final EmailSender emailSender;
|
||||
private final ApplicationRepository applicationRepository;
|
||||
|
||||
private final PolicySolution policySolution;
|
||||
private final CommonConfig commonConfig;
|
||||
private final EmailConfig emailConfig;
|
||||
private final UserChangedHandler userChangedHandler;
|
||||
private final EncryptionService encryptionService;
|
||||
private final UserDataService userDataService;
|
||||
private final TenantService tenantService;
|
||||
private final PermissionGroupService permissionGroupService;
|
||||
private final UserUtils userUtils;
|
||||
private final EmailService emailService;
|
||||
private final RateLimitService rateLimitService;
|
||||
private final RedirectHelper redirectHelper;
|
||||
|
||||
private static final WebFilterChain EMPTY_WEB_FILTER_CHAIN = serverWebExchange -> Mono.empty();
|
||||
|
||||
private static final String WELCOME_USER_EMAIL_TEMPLATE = "email/welcomeUserTemplate.html";
|
||||
private static final String FORGOT_PASSWORD_EMAIL_TEMPLATE = "email/forgotPasswordTemplate.html";
|
||||
private static final String FORGOT_PASSWORD_CLIENT_URL_FORMAT = "%s/user/resetPassword?token=%s";
|
||||
private static final String INVITE_USER_CLIENT_URL_FORMAT = "%s/user/signup?email=%s";
|
||||
public static final String INVITE_USER_EMAIL_TEMPLATE = "email/inviteUserTemplate.html";
|
||||
private static final Pattern ALLOWED_ACCENTED_CHARACTERS_PATTERN = Pattern.compile("^[\\p{L} 0-9 .\'\\-]+$");
|
||||
|
||||
private static final String EMAIL_VERIFICATION_CLIENT_URL_FORMAT =
|
||||
"%s/user/verify?token=%s&email=%s&redirectUrl=%s";
|
||||
|
||||
private static final String EMAIL_VERIFICATION_ERROR_URL_FORMAT = "/user/verify-error?code=%s&message=%s&email=%s";
|
||||
private static final String USER_EMAIL_VERIFICATION_EMAIL_TEMPLATE = "email/emailVerificationTemplate.html";
|
||||
private final EmailVerificationTokenRepository emailVerificationTokenRepository;
|
||||
|
||||
private final ServerRedirectStrategy redirectStrategy = new DefaultServerRedirectStrategy();
|
||||
|
|
@ -162,18 +152,16 @@ public class UserServiceCEImpl extends BaseService<UserRepository, User, String>
|
|||
PermissionGroupService permissionGroupService,
|
||||
UserUtils userUtils,
|
||||
EmailVerificationTokenRepository emailVerificationTokenRepository,
|
||||
RedirectHelper redirectHelper,
|
||||
EmailService emailService,
|
||||
RateLimitService rateLimitService) {
|
||||
|
||||
super(scheduler, validator, mongoConverter, reactiveMongoTemplate, repository, analyticsService);
|
||||
this.workspaceService = workspaceService;
|
||||
this.sessionUserService = sessionUserService;
|
||||
this.passwordResetTokenRepository = passwordResetTokenRepository;
|
||||
this.passwordEncoder = passwordEncoder;
|
||||
this.emailSender = emailSender;
|
||||
this.applicationRepository = applicationRepository;
|
||||
this.policySolution = policySolution;
|
||||
this.commonConfig = commonConfig;
|
||||
this.emailConfig = emailConfig;
|
||||
this.userChangedHandler = userChangedHandler;
|
||||
this.encryptionService = encryptionService;
|
||||
this.userDataService = userDataService;
|
||||
|
|
@ -182,7 +170,7 @@ public class UserServiceCEImpl extends BaseService<UserRepository, User, String>
|
|||
this.userUtils = userUtils;
|
||||
this.rateLimitService = rateLimitService;
|
||||
this.emailVerificationTokenRepository = emailVerificationTokenRepository;
|
||||
this.redirectHelper = redirectHelper;
|
||||
this.emailService = emailService;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
@ -302,12 +290,7 @@ public class UserServiceCEImpl extends BaseService<UserRepository, User, String>
|
|||
|
||||
log.debug("Password reset url for email: {}: {}", passwordResetToken.getEmail(), resetUrl);
|
||||
|
||||
Map<String, String> params = new HashMap<>();
|
||||
params.put("resetUrl", resetUrl);
|
||||
|
||||
return updateTenantLogoInParams(params, resetUserPasswordDTO.getBaseUrl())
|
||||
.flatMap(updatedParams -> emailSender.sendMail(
|
||||
email, "Appsmith Password Reset", FORGOT_PASSWORD_EMAIL_TEMPLATE, updatedParams));
|
||||
return emailService.sendForgotPasswordEmail(email, resetUrl, resetUserPasswordDTO.getBaseUrl());
|
||||
})
|
||||
.thenReturn(true);
|
||||
}
|
||||
|
|
@ -446,7 +429,7 @@ public class UserServiceCEImpl extends BaseService<UserRepository, User, String>
|
|||
@Override
|
||||
public Mono<User> create(User user) {
|
||||
// This is the path that is taken when a new user signs up on its own
|
||||
return createUser(user, null).map(UserSignupDTO::getUser);
|
||||
return createUser(user).map(UserSignupDTO::getUser);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
@ -510,12 +493,7 @@ public class UserServiceCEImpl extends BaseService<UserRepository, User, String>
|
|||
}
|
||||
|
||||
@Override
|
||||
public Mono<UserSignupDTO> createUser(User user, String originHeader) {
|
||||
if (originHeader == null || originHeader.isBlank()) {
|
||||
// Default to the production link
|
||||
originHeader = Appsmith.DEFAULT_ORIGIN_HEADER;
|
||||
}
|
||||
|
||||
public Mono<UserSignupDTO> createUser(User user) {
|
||||
// Only encode the password if it's a form signup. For OAuth signups, we don't need password
|
||||
if (LoginSource.FORM.equals(user.getSource())) {
|
||||
if (user.getPassword() == null || user.getPassword().isBlank()) {
|
||||
|
|
@ -597,17 +575,6 @@ public class UserServiceCEImpl extends BaseService<UserRepository, User, String>
|
|||
* @param user User object representing the user to be created/enabled.
|
||||
* @return Publishes the user object, after having been saved.
|
||||
*/
|
||||
@Override
|
||||
public Mono<UserSignupDTO> createUserAndSendEmail(User user, String originHeader) {
|
||||
return createUser(user, originHeader).flatMap(userSignupDTO -> {
|
||||
User savedUser = userSignupDTO.getUser();
|
||||
Mono<User> userMono = emailConfig.isWelcomeEmailEnabled()
|
||||
? sendWelcomeEmail(savedUser, originHeader)
|
||||
: Mono.just(savedUser);
|
||||
return userMono.thenReturn(userSignupDTO);
|
||||
});
|
||||
}
|
||||
|
||||
private Mono<User> signupIfAllowed(User user) {
|
||||
boolean isAdminUser = false;
|
||||
|
||||
|
|
@ -642,30 +609,6 @@ public class UserServiceCEImpl extends BaseService<UserRepository, User, String>
|
|||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
public Mono<User> sendWelcomeEmail(User user, String originHeader) {
|
||||
Map<String, String> params = new HashMap<>();
|
||||
params.put("primaryLinkUrl", originHeader);
|
||||
|
||||
return updateTenantLogoInParams(params, originHeader)
|
||||
.flatMap(updatedParams -> emailSender.sendMail(
|
||||
user.getEmail(), "Welcome to Appsmith", WELCOME_USER_EMAIL_TEMPLATE, updatedParams))
|
||||
.elapsed()
|
||||
.map(pair -> {
|
||||
log.debug("UserServiceCEImpl::Time taken to send email: {} ms", pair.getT1());
|
||||
return pair.getT2();
|
||||
})
|
||||
.onErrorResume(error -> {
|
||||
// Swallowing this exception because we don't want this to affect the rest of the flow.
|
||||
log.error(
|
||||
"Ignoring error: Unable to send welcome email to the user {}. Cause: ",
|
||||
user.getEmail(),
|
||||
Exceptions.unwrap(error));
|
||||
return Mono.just(TRUE);
|
||||
})
|
||||
.thenReturn(user);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Mono<User> update(String id, User userUpdate) {
|
||||
Mono<User> userFromRepository = repository
|
||||
|
|
@ -702,41 +645,6 @@ public class UserServiceCEImpl extends BaseService<UserRepository, User, String>
|
|||
return repository.save(existingUser).map(userChangedHandler::publish);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Mono<? extends User> createNewUserAndSendInviteEmail(
|
||||
String email, String originHeader, Workspace workspace, User inviter, String role) {
|
||||
User newUser = new User();
|
||||
newUser.setEmail(email.toLowerCase());
|
||||
|
||||
// This is a new user. Till the user signs up, this user would be disabled.
|
||||
newUser.setIsEnabled(false);
|
||||
|
||||
// The invite token is not used today and doesn't need to be verified. We still save the invite token with the
|
||||
// role information to classify the user persona.
|
||||
newUser.setInviteToken(role + ":" + UUID.randomUUID());
|
||||
|
||||
boolean isAdminUser = commonConfig.getAdminEmails().contains(email.toLowerCase());
|
||||
|
||||
// Call user service's userCreate function so that the default workspace, etc are also created along with
|
||||
// assigning basic permissions.
|
||||
return userCreate(newUser, isAdminUser).flatMap(createdUser -> {
|
||||
log.debug("Going to send email for invite user to {}", createdUser.getEmail());
|
||||
String inviteUrl = String.format(
|
||||
INVITE_USER_CLIENT_URL_FORMAT,
|
||||
originHeader,
|
||||
URLEncoder.encode(createdUser.getEmail(), StandardCharsets.UTF_8));
|
||||
|
||||
// Email template parameters initialization below.
|
||||
Map<String, String> params = getEmailParams(workspace, inviter, inviteUrl, true);
|
||||
|
||||
// We have sent out the emails. Just send back the saved user.
|
||||
return updateTenantLogoInParams(params, originHeader)
|
||||
.flatMap(updatedParams -> emailSender.sendMail(
|
||||
createdUser.getEmail(), "Invite for Appsmith", INVITE_USER_EMAIL_TEMPLATE, updatedParams))
|
||||
.thenReturn(createdUser);
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
public Flux<User> get(MultiValueMap<String, String> params) {
|
||||
// Get All Users should not be supported. Return an error
|
||||
|
|
@ -806,30 +714,6 @@ public class UserServiceCEImpl extends BaseService<UserRepository, User, String>
|
|||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
public Map<String, String> getEmailParams(Workspace workspace, User inviter, String inviteUrl, boolean isNewUser) {
|
||||
Map<String, String> params = new HashMap<>();
|
||||
|
||||
if (inviter != null) {
|
||||
params.put(
|
||||
"inviterFirstName",
|
||||
org.apache.commons.lang3.StringUtils.defaultIfEmpty(inviter.getName(), inviter.getEmail()));
|
||||
}
|
||||
if (workspace != null) {
|
||||
params.put("inviterWorkspaceName", workspace.getName());
|
||||
}
|
||||
if (isNewUser) {
|
||||
params.put("primaryLinkUrl", inviteUrl);
|
||||
params.put("primaryLinkText", "Sign up now");
|
||||
} else {
|
||||
if (workspace != null) {
|
||||
params.put("primaryLinkUrl", inviteUrl + "/applications#" + workspace.getId());
|
||||
}
|
||||
params.put("primaryLinkText", "Go to workspace");
|
||||
}
|
||||
return params;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Mono<Boolean> isUsersEmpty() {
|
||||
return repository.isUsersEmpty();
|
||||
|
|
@ -892,11 +776,6 @@ public class UserServiceCEImpl extends BaseService<UserRepository, User, String>
|
|||
return repository.findAllByEmails(emails);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Mono<Map<String, String>> updateTenantLogoInParams(Map<String, String> params, String origin) {
|
||||
return Mono.just(params);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Mono<Boolean> resendEmailVerification(
|
||||
ResendEmailVerificationDTO resendEmailVerificationDTO, String redirectUrl) {
|
||||
|
|
@ -971,21 +850,7 @@ public class UserServiceCEImpl extends BaseService<UserRepository, User, String>
|
|||
URLEncoder.encode(emailVerificationToken.getEmail(), StandardCharsets.UTF_8),
|
||||
redirectUrlCopy);
|
||||
|
||||
log.debug(
|
||||
"Email Verification url for email: {}: {}",
|
||||
emailVerificationToken.getEmail(),
|
||||
verificationUrl);
|
||||
|
||||
Map<String, String> params = new HashMap<>();
|
||||
|
||||
params.put("verificationUrl", verificationUrl);
|
||||
|
||||
return updateTenantLogoInParams(params, resendEmailVerificationDTO.getBaseUrl())
|
||||
.flatMap(updatedParams -> emailSender.sendMail(
|
||||
email,
|
||||
"Verify your account",
|
||||
USER_EMAIL_VERIFICATION_EMAIL_TEMPLATE,
|
||||
updatedParams));
|
||||
return emailService.sendEmailVerificationEmail(user, verificationUrl);
|
||||
})
|
||||
.thenReturn(true);
|
||||
}
|
||||
|
|
@ -1092,11 +957,7 @@ public class UserServiceCEImpl extends BaseService<UserRepository, User, String>
|
|||
user.setEmailVerified(TRUE);
|
||||
Mono<Void> redirectionMono = redirectStrategy.sendRedirect(
|
||||
webFilterExchange.getExchange(), URI.create(postVerificationRedirectUrl));
|
||||
Mono<User> welcomeEmailMono = sendWelcomeEmail(user, baseUrl);
|
||||
return repository
|
||||
.save(user)
|
||||
.then(Mono.zip(welcomeEmailMono, redirectionMono))
|
||||
.flatMap(objects -> Mono.just(objects.getT2()));
|
||||
return repository.save(user).then(redirectionMono);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
|
|
|||
|
|
@ -3,7 +3,6 @@ package com.appsmith.server.services.ce_compatible;
|
|||
import com.appsmith.external.services.EncryptionService;
|
||||
import com.appsmith.server.configurations.CommonConfig;
|
||||
import com.appsmith.server.configurations.EmailConfig;
|
||||
import com.appsmith.server.helpers.RedirectHelper;
|
||||
import com.appsmith.server.helpers.UserUtils;
|
||||
import com.appsmith.server.notifications.EmailSender;
|
||||
import com.appsmith.server.ratelimiting.RateLimitService;
|
||||
|
|
@ -12,6 +11,7 @@ import com.appsmith.server.repositories.EmailVerificationTokenRepository;
|
|||
import com.appsmith.server.repositories.PasswordResetTokenRepository;
|
||||
import com.appsmith.server.repositories.UserRepository;
|
||||
import com.appsmith.server.services.AnalyticsService;
|
||||
import com.appsmith.server.services.EmailService;
|
||||
import com.appsmith.server.services.PermissionGroupService;
|
||||
import com.appsmith.server.services.SessionUserService;
|
||||
import com.appsmith.server.services.TenantService;
|
||||
|
|
@ -52,7 +52,7 @@ public class UserServiceCECompatibleImpl extends UserServiceCEImpl implements Us
|
|||
PermissionGroupService permissionGroupService,
|
||||
UserUtils userUtils,
|
||||
EmailVerificationTokenRepository emailVerificationTokenRepository,
|
||||
RedirectHelper redirectHelper,
|
||||
EmailService emailService,
|
||||
RateLimitService rateLimitService) {
|
||||
super(
|
||||
scheduler,
|
||||
|
|
@ -77,7 +77,7 @@ public class UserServiceCECompatibleImpl extends UserServiceCEImpl implements Us
|
|||
permissionGroupService,
|
||||
userUtils,
|
||||
emailVerificationTokenRepository,
|
||||
redirectHelper,
|
||||
emailService,
|
||||
rateLimitService);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -9,6 +9,7 @@ import com.appsmith.server.notifications.EmailSender;
|
|||
import com.appsmith.server.repositories.UserRepository;
|
||||
import com.appsmith.server.services.AnalyticsService;
|
||||
import com.appsmith.server.services.ConfigService;
|
||||
import com.appsmith.server.services.EmailService;
|
||||
import com.appsmith.server.services.PermissionGroupService;
|
||||
import com.appsmith.server.services.SessionUserService;
|
||||
import com.appsmith.server.services.TenantService;
|
||||
|
|
@ -38,7 +39,8 @@ public class EnvManagerImpl extends EnvManagerCEImpl implements EnvManager {
|
|||
ConfigService configService,
|
||||
UserUtils userUtils,
|
||||
TenantService tenantService,
|
||||
ObjectMapper objectMapper) {
|
||||
ObjectMapper objectMapper,
|
||||
EmailService emailService) {
|
||||
|
||||
super(
|
||||
sessionUserService,
|
||||
|
|
@ -55,6 +57,7 @@ public class EnvManagerImpl extends EnvManagerCEImpl implements EnvManager {
|
|||
configService,
|
||||
userUtils,
|
||||
tenantService,
|
||||
objectMapper);
|
||||
objectMapper,
|
||||
emailService);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,8 +1,9 @@
|
|||
package com.appsmith.server.solutions;
|
||||
|
||||
import com.appsmith.server.notifications.EmailSender;
|
||||
import com.appsmith.server.configurations.CommonConfig;
|
||||
import com.appsmith.server.repositories.UserRepository;
|
||||
import com.appsmith.server.services.AnalyticsService;
|
||||
import com.appsmith.server.services.EmailService;
|
||||
import com.appsmith.server.services.PermissionGroupService;
|
||||
import com.appsmith.server.services.SessionUserService;
|
||||
import com.appsmith.server.services.UserService;
|
||||
|
|
@ -23,8 +24,9 @@ public class UserAndAccessManagementServiceImpl extends UserAndAccessManagementS
|
|||
UserRepository userRepository,
|
||||
AnalyticsService analyticsService,
|
||||
UserService userService,
|
||||
EmailSender emailSender,
|
||||
PermissionGroupPermission permissionGroupPermission) {
|
||||
PermissionGroupPermission permissionGroupPermission,
|
||||
EmailService emailService,
|
||||
CommonConfig commonConfig) {
|
||||
|
||||
super(
|
||||
sessionUserService,
|
||||
|
|
@ -33,7 +35,8 @@ public class UserAndAccessManagementServiceImpl extends UserAndAccessManagementS
|
|||
userRepository,
|
||||
analyticsService,
|
||||
userService,
|
||||
emailSender,
|
||||
permissionGroupPermission);
|
||||
permissionGroupPermission,
|
||||
emailService,
|
||||
commonConfig);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -7,6 +7,7 @@ import com.appsmith.server.helpers.UserUtils;
|
|||
import com.appsmith.server.services.AnalyticsService;
|
||||
import com.appsmith.server.services.CaptchaService;
|
||||
import com.appsmith.server.services.ConfigService;
|
||||
import com.appsmith.server.services.EmailService;
|
||||
import com.appsmith.server.services.UserDataService;
|
||||
import com.appsmith.server.services.UserService;
|
||||
import com.appsmith.server.solutions.ce.UserSignupCEImpl;
|
||||
|
|
@ -27,7 +28,8 @@ public class UserSignupImpl extends UserSignupCEImpl implements UserSignup {
|
|||
EnvManager envManager,
|
||||
CommonConfig commonConfig,
|
||||
UserUtils userUtils,
|
||||
NetworkUtils networkUtils) {
|
||||
NetworkUtils networkUtils,
|
||||
EmailService emailService) {
|
||||
|
||||
super(
|
||||
userService,
|
||||
|
|
@ -39,6 +41,7 @@ public class UserSignupImpl extends UserSignupCEImpl implements UserSignup {
|
|||
envManager,
|
||||
commonConfig,
|
||||
userUtils,
|
||||
networkUtils);
|
||||
networkUtils,
|
||||
emailService);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -14,9 +14,9 @@ public interface EnvManagerCE {
|
|||
|
||||
List<String> transformEnvContent(String envContent, Map<String, String> changes);
|
||||
|
||||
Mono<Void> applyChanges(Map<String, String> changes);
|
||||
Mono<Void> applyChanges(Map<String, String> changes, String originHeader);
|
||||
|
||||
Mono<Void> applyChangesFromMultipartFormData(MultiValueMap<String, Part> formData);
|
||||
Mono<Void> applyChangesFromMultipartFormData(MultiValueMap<String, Part> formData, String originHeader);
|
||||
|
||||
void setAnalyticsEventAction(
|
||||
Map<String, Object> properties, String newVariable, String originalVariable, String authEnv);
|
||||
|
|
|
|||
|
|
@ -21,6 +21,7 @@ import com.appsmith.server.notifications.EmailSender;
|
|||
import com.appsmith.server.repositories.UserRepository;
|
||||
import com.appsmith.server.services.AnalyticsService;
|
||||
import com.appsmith.server.services.ConfigService;
|
||||
import com.appsmith.server.services.EmailService;
|
||||
import com.appsmith.server.services.PermissionGroupService;
|
||||
import com.appsmith.server.services.SessionUserService;
|
||||
import com.appsmith.server.services.TenantService;
|
||||
|
|
@ -115,6 +116,8 @@ public class EnvManagerCEImpl implements EnvManagerCE {
|
|||
|
||||
private final ObjectMapper objectMapper;
|
||||
|
||||
private final EmailService emailService;
|
||||
|
||||
/**
|
||||
* This regex pattern matches environment variable declarations like `VAR_NAME=value` or `VAR_NAME="value"` or just
|
||||
* `VAR_NAME=`. It also defines two named capture groups, `name` and `value`, for the variable's name and value
|
||||
|
|
@ -140,7 +143,8 @@ public class EnvManagerCEImpl implements EnvManagerCE {
|
|||
ConfigService configService,
|
||||
UserUtils userUtils,
|
||||
TenantService tenantService,
|
||||
ObjectMapper objectMapper) {
|
||||
ObjectMapper objectMapper,
|
||||
EmailService emailService) {
|
||||
|
||||
this.sessionUserService = sessionUserService;
|
||||
this.userService = userService;
|
||||
|
|
@ -157,6 +161,7 @@ public class EnvManagerCEImpl implements EnvManagerCE {
|
|||
this.userUtils = userUtils;
|
||||
this.tenantService = tenantService;
|
||||
this.objectMapper = objectMapper;
|
||||
this.emailService = emailService;
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -335,7 +340,7 @@ public class EnvManagerCEImpl implements EnvManagerCE {
|
|||
}
|
||||
|
||||
@Override
|
||||
public Mono<Void> applyChanges(Map<String, String> changes) {
|
||||
public Mono<Void> applyChanges(Map<String, String> changes, String originHeader) {
|
||||
// This flow is pertinent for any variables that need to change in the .env file or be saved in the tenant
|
||||
// configuration
|
||||
return verifyCurrentUserIsSuper()
|
||||
|
|
@ -396,7 +401,7 @@ public class EnvManagerCEImpl implements EnvManagerCE {
|
|||
commonConfig.setAdminEmails(changesCopy.remove(APPSMITH_ADMIN_EMAILS.name()));
|
||||
String oldAdminEmailsCsv = originalValues.get(APPSMITH_ADMIN_EMAILS.name());
|
||||
dependentTasks = dependentTasks
|
||||
.then(updateAdminUserPolicies(oldAdminEmailsCsv))
|
||||
.then(updateAdminUserPolicies(oldAdminEmailsCsv, originHeader))
|
||||
.then();
|
||||
}
|
||||
|
||||
|
|
@ -449,7 +454,7 @@ public class EnvManagerCEImpl implements EnvManagerCE {
|
|||
}
|
||||
|
||||
@Override
|
||||
public Mono<Void> applyChangesFromMultipartFormData(MultiValueMap<String, Part> formData) {
|
||||
public Mono<Void> applyChangesFromMultipartFormData(MultiValueMap<String, Part> formData, String originHeader) {
|
||||
return Flux.fromIterable(formData.entrySet())
|
||||
.flatMap(entry -> {
|
||||
final String key = entry.getKey();
|
||||
|
|
@ -474,7 +479,7 @@ public class EnvManagerCEImpl implements EnvManagerCE {
|
|||
});
|
||||
})
|
||||
.collectMap(Map.Entry::getKey, Map.Entry::getValue)
|
||||
.flatMap(this::applyChanges);
|
||||
.flatMap(changesMap -> this.applyChanges(changesMap, originHeader));
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
@ -571,7 +576,7 @@ public class EnvManagerCEImpl implements EnvManagerCE {
|
|||
*
|
||||
* @param oldAdminEmailsCsv comma separated email addresses that was set as admin email earlier
|
||||
*/
|
||||
private Mono<Boolean> updateAdminUserPolicies(String oldAdminEmailsCsv) {
|
||||
private Mono<Boolean> updateAdminUserPolicies(String oldAdminEmailsCsv, String originHeader) {
|
||||
Set<String> oldAdminEmails = TextUtils.csvToSet(oldAdminEmailsCsv);
|
||||
Set<String> newAdminEmails = commonConfig.getAdminEmails();
|
||||
|
||||
|
|
@ -584,14 +589,48 @@ public class EnvManagerCEImpl implements EnvManagerCE {
|
|||
Mono<Boolean> removedUsersMono = Flux.fromIterable(removedUsers)
|
||||
.flatMap(userService::findByEmail)
|
||||
.collectList()
|
||||
.flatMap(users -> userUtils.removeSuperUser(users));
|
||||
.flatMap(userUtils::removeSuperUser);
|
||||
|
||||
Mono<Boolean> newUsersMono = Flux.fromIterable(newUsers)
|
||||
.flatMap(userService::findByEmail)
|
||||
Flux<User> usersFlux = Flux.fromIterable(newUsers)
|
||||
.flatMap(email -> userService.findByEmail(email).map(existingUser -> {
|
||||
if (existingUser == null) {
|
||||
User newUser = new User();
|
||||
newUser.setEmail(email);
|
||||
newUser.setIsEnabled(false);
|
||||
return newUser;
|
||||
}
|
||||
return existingUser;
|
||||
}))
|
||||
.cache();
|
||||
|
||||
Flux<User> newUsersFlux = usersFlux.filter(user -> !user.isEnabled());
|
||||
Flux<User> existingUsersFlux = usersFlux.filter(User::isEnabled);
|
||||
|
||||
// we are sending email to existing users who are not already super-users
|
||||
Mono<List<User>> existingUsersWhichAreNotAlreadySuperUsersMono = existingUsersFlux
|
||||
.filterWhen(user -> userUtils.isSuperUser(user).map(isSuper -> !isSuper))
|
||||
.collectList();
|
||||
|
||||
Mono<Boolean> newUsersMono = newUsersFlux
|
||||
.flatMap(newUsersFluxUser -> sessionUserService
|
||||
.getCurrentUser()
|
||||
.flatMap(invitingUser -> emailService.sendInstanceAdminInviteEmail(
|
||||
newUsersFluxUser, invitingUser, originHeader, true)))
|
||||
.collectList()
|
||||
.flatMap(users -> userUtils.makeSuperUser(users));
|
||||
.map(results -> results.stream().allMatch(result -> result));
|
||||
|
||||
return Mono.when(removedUsersMono, newUsersMono).then(Mono.just(TRUE));
|
||||
Mono<Boolean> existingUsersMono = existingUsersWhichAreNotAlreadySuperUsersMono.flatMap(users -> userUtils
|
||||
.makeSuperUser(users)
|
||||
.flatMap(
|
||||
success -> Flux.fromIterable(users)
|
||||
.flatMap(user -> sessionUserService
|
||||
.getCurrentUser()
|
||||
.flatMap(invitingUser -> emailService.sendInstanceAdminInviteEmail(
|
||||
user, invitingUser, originHeader, false)))
|
||||
.then(Mono.just(success)) // Emit 'success' as the result
|
||||
));
|
||||
|
||||
return Mono.when(removedUsersMono, newUsersMono, existingUsersMono).map(tuple -> TRUE);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
package com.appsmith.server.solutions.ce;
|
||||
|
||||
import com.appsmith.external.constants.AnalyticsEvents;
|
||||
import com.appsmith.server.configurations.CommonConfig;
|
||||
import com.appsmith.server.constants.FieldName;
|
||||
import com.appsmith.server.domains.PermissionGroup;
|
||||
import com.appsmith.server.domains.User;
|
||||
|
|
@ -8,9 +9,9 @@ import com.appsmith.server.domains.Workspace;
|
|||
import com.appsmith.server.dtos.InviteUsersDTO;
|
||||
import com.appsmith.server.exceptions.AppsmithError;
|
||||
import com.appsmith.server.exceptions.AppsmithException;
|
||||
import com.appsmith.server.notifications.EmailSender;
|
||||
import com.appsmith.server.repositories.UserRepository;
|
||||
import com.appsmith.server.services.AnalyticsService;
|
||||
import com.appsmith.server.services.EmailService;
|
||||
import com.appsmith.server.services.PermissionGroupService;
|
||||
import com.appsmith.server.services.SessionUserService;
|
||||
import com.appsmith.server.services.UserService;
|
||||
|
|
@ -21,6 +22,8 @@ import org.springframework.util.CollectionUtils;
|
|||
import org.springframework.util.StringUtils;
|
||||
import reactor.core.publisher.Flux;
|
||||
import reactor.core.publisher.Mono;
|
||||
import reactor.util.function.Tuple2;
|
||||
import reactor.util.function.Tuples;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
|
|
@ -28,7 +31,6 @@ import java.util.List;
|
|||
import java.util.Map;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import static com.appsmith.server.services.ce.UserServiceCEImpl.INVITE_USER_EMAIL_TEMPLATE;
|
||||
import static java.lang.Boolean.TRUE;
|
||||
|
||||
@Slf4j
|
||||
|
|
@ -40,8 +42,9 @@ public class UserAndAccessManagementServiceCEImpl implements UserAndAccessManage
|
|||
private final UserRepository userRepository;
|
||||
private final AnalyticsService analyticsService;
|
||||
private final UserService userService;
|
||||
private final EmailSender emailSender;
|
||||
private final PermissionGroupPermission permissionGroupPermission;
|
||||
private final EmailService emailService;
|
||||
private final CommonConfig commonConfig;
|
||||
|
||||
public UserAndAccessManagementServiceCEImpl(
|
||||
SessionUserService sessionUserService,
|
||||
|
|
@ -50,8 +53,9 @@ public class UserAndAccessManagementServiceCEImpl implements UserAndAccessManage
|
|||
UserRepository userRepository,
|
||||
AnalyticsService analyticsService,
|
||||
UserService userService,
|
||||
EmailSender emailSender,
|
||||
PermissionGroupPermission permissionGroupPermission) {
|
||||
PermissionGroupPermission permissionGroupPermission,
|
||||
EmailService emailService,
|
||||
CommonConfig commonConfig) {
|
||||
|
||||
this.sessionUserService = sessionUserService;
|
||||
this.permissionGroupService = permissionGroupService;
|
||||
|
|
@ -59,8 +63,9 @@ public class UserAndAccessManagementServiceCEImpl implements UserAndAccessManage
|
|||
this.userRepository = userRepository;
|
||||
this.analyticsService = analyticsService;
|
||||
this.userService = userService;
|
||||
this.emailSender = emailSender;
|
||||
this.emailService = emailService;
|
||||
this.permissionGroupPermission = permissionGroupPermission;
|
||||
this.commonConfig = commonConfig;
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -125,57 +130,38 @@ public class UserAndAccessManagementServiceCEImpl implements UserAndAccessManage
|
|||
|
||||
// Check if the invited user exists. If yes, return the user, else create a new user by triggering
|
||||
// createNewUserAndSendInviteEmail. In both the cases, send the appropriate emails
|
||||
Mono<List<User>> inviteUsersMono = Flux.fromIterable(usernames)
|
||||
.flatMap(username -> Mono.zip(
|
||||
Mono.just(username),
|
||||
workspaceMono,
|
||||
currentUserMono,
|
||||
permissionGroupMono,
|
||||
defaultPermissionGroupsMono))
|
||||
Mono<List<Tuple2<User, Boolean>>> inviteUsersMonoWithUserCreationMapping = Flux.fromIterable(usernames)
|
||||
.flatMap(username -> Mono.zip(Mono.just(username), workspaceMono, defaultPermissionGroupsMono))
|
||||
.flatMap(tuple -> {
|
||||
String username = tuple.getT1();
|
||||
Workspace workspace = tuple.getT2();
|
||||
eventData.put(FieldName.WORKSPACE, workspace);
|
||||
User currentUser = tuple.getT3();
|
||||
PermissionGroup permissionGroup = tuple.getT4();
|
||||
List<PermissionGroup> defaultPermissionGroups = tuple.getT5();
|
||||
List<PermissionGroup> defaultPermissionGroups = tuple.getT3();
|
||||
|
||||
Mono<User> getUserFromDbAndCheckIfUserExists = userRepository
|
||||
.findByEmail(username)
|
||||
.flatMap(user -> {
|
||||
return throwErrorIfUserAlreadyExistsInWorkspace(user, defaultPermissionGroups)
|
||||
// If no errors, proceed forward
|
||||
.thenReturn(user);
|
||||
});
|
||||
.flatMap(user -> throwErrorIfUserAlreadyExistsInWorkspace(user, defaultPermissionGroups)
|
||||
.thenReturn(user));
|
||||
|
||||
return getUserFromDbAndCheckIfUserExists
|
||||
.flatMap(existingUser -> {
|
||||
// The user already existed, just send an email informing that the user has been added
|
||||
// to a new workspace
|
||||
log.debug(
|
||||
"Going to send email to user {} informing that the user has been added to new workspace {}",
|
||||
existingUser.getEmail(),
|
||||
workspace.getName());
|
||||
|
||||
// Email template parameters initialization below.
|
||||
Map<String, String> params =
|
||||
userService.getEmailParams(workspace, currentUser, originHeader, false);
|
||||
|
||||
.flatMap(existingUser -> Mono.just(Tuples.of(existingUser, false)))
|
||||
.switchIfEmpty(Mono.defer(() -> {
|
||||
User newUser = new User();
|
||||
newUser.setEmail(username.toLowerCase());
|
||||
newUser.setIsEnabled(false);
|
||||
boolean isAdminUser = false;
|
||||
return userService
|
||||
.updateTenantLogoInParams(params, originHeader)
|
||||
.flatMap(updatedParams -> emailSender.sendMail(
|
||||
existingUser.getEmail(),
|
||||
"Appsmith: You have been added to a new workspace",
|
||||
INVITE_USER_EMAIL_TEMPLATE,
|
||||
updatedParams))
|
||||
.thenReturn(existingUser);
|
||||
})
|
||||
.switchIfEmpty(userService.createNewUserAndSendInviteEmail(
|
||||
username, originHeader, workspace, currentUser, permissionGroup.getName()));
|
||||
.userCreate(newUser, isAdminUser)
|
||||
.flatMap(newCreatedUser -> Mono.just(Tuples.of(newCreatedUser, true)));
|
||||
}));
|
||||
})
|
||||
.collectList()
|
||||
.cache();
|
||||
|
||||
Mono<List<User>> inviteUsersMono = inviteUsersMonoWithUserCreationMapping
|
||||
.map(tuple2s -> tuple2s.stream().map(Tuple2::getT1).collect(Collectors.toList()))
|
||||
.cache();
|
||||
|
||||
// assign permission group to the invited users.
|
||||
Mono<PermissionGroup> bulkAddUserResultMono = Mono.zip(permissionGroupMono, inviteUsersMono)
|
||||
.flatMap(tuple -> {
|
||||
|
|
@ -203,7 +189,28 @@ public class UserAndAccessManagementServiceCEImpl implements UserAndAccessManage
|
|||
AnalyticsEvents.EXECUTE_INVITE_USERS, currentUser, analyticsProperties);
|
||||
});
|
||||
|
||||
return bulkAddUserResultMono.then(sendAnalyticsEventMono).then(inviteUsersMono);
|
||||
Mono<Boolean> sendEmailsMono = Mono.zip(
|
||||
inviteUsersMonoWithUserCreationMapping, workspaceMono, currentUserMono, permissionGroupMono)
|
||||
.flatMap(tuple -> {
|
||||
List<Tuple2<User, Boolean>> users = tuple.getT1();
|
||||
Workspace workspace = tuple.getT2();
|
||||
User currentUser = tuple.getT3();
|
||||
PermissionGroup permissionGroup = tuple.getT4();
|
||||
|
||||
return Flux.fromIterable(users)
|
||||
.flatMap(userTuple -> {
|
||||
User user = userTuple.getT1();
|
||||
boolean isNewUser = userTuple.getT2();
|
||||
return emailService.sendInviteUserToWorkspaceEmail(
|
||||
currentUser, user, workspace, permissionGroup, originHeader, isNewUser);
|
||||
})
|
||||
.all(emailSent -> emailSent);
|
||||
});
|
||||
|
||||
return bulkAddUserResultMono
|
||||
.then(sendAnalyticsEventMono)
|
||||
.then(sendEmailsMono)
|
||||
.then(inviteUsersMono);
|
||||
}
|
||||
|
||||
private Mono<Boolean> throwErrorIfUserAlreadyExistsInWorkspace(
|
||||
|
|
|
|||
|
|
@ -27,7 +27,8 @@ public interface UserSignupCE {
|
|||
*/
|
||||
Mono<Void> signupAndLoginFromFormData(ServerWebExchange exchange);
|
||||
|
||||
Mono<User> signupAndLoginSuper(UserSignupRequestDTO userFromRequest, ServerWebExchange exchange);
|
||||
Mono<User> signupAndLoginSuper(
|
||||
UserSignupRequestDTO userFromRequest, String originHeader, ServerWebExchange exchange);
|
||||
|
||||
Mono<Void> signupAndLoginSuperFromFormData(ServerWebExchange exchange);
|
||||
Mono<Void> signupAndLoginSuperFromFormData(String originHeader, ServerWebExchange exchange);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -17,6 +17,7 @@ import com.appsmith.server.helpers.UserUtils;
|
|||
import com.appsmith.server.services.AnalyticsService;
|
||||
import com.appsmith.server.services.CaptchaService;
|
||||
import com.appsmith.server.services.ConfigService;
|
||||
import com.appsmith.server.services.EmailService;
|
||||
import com.appsmith.server.services.UserDataService;
|
||||
import com.appsmith.server.services.UserService;
|
||||
import com.appsmith.server.solutions.EnvManager;
|
||||
|
|
@ -75,6 +76,7 @@ public class UserSignupCEImpl implements UserSignupCE {
|
|||
private final CommonConfig commonConfig;
|
||||
private final UserUtils userUtils;
|
||||
private final NetworkUtils networkUtils;
|
||||
private final EmailService emailService;
|
||||
|
||||
private static final ServerRedirectStrategy redirectStrategy = new DefaultServerRedirectStrategy();
|
||||
|
||||
|
|
@ -90,7 +92,8 @@ public class UserSignupCEImpl implements UserSignupCE {
|
|||
EnvManager envManager,
|
||||
CommonConfig commonConfig,
|
||||
UserUtils userUtils,
|
||||
NetworkUtils networkUtils) {
|
||||
NetworkUtils networkUtils,
|
||||
EmailService emailService) {
|
||||
|
||||
this.userService = userService;
|
||||
this.userDataService = userDataService;
|
||||
|
|
@ -102,6 +105,7 @@ public class UserSignupCEImpl implements UserSignupCE {
|
|||
this.commonConfig = commonConfig;
|
||||
this.userUtils = userUtils;
|
||||
this.networkUtils = networkUtils;
|
||||
this.emailService = emailService;
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -126,15 +130,15 @@ public class UserSignupCEImpl implements UserSignupCE {
|
|||
}
|
||||
|
||||
// only creating user, welcome email will be sent post user email verification
|
||||
Mono<UserSignupDTO> createUserAndSendEmailMono = userService
|
||||
.createUser(user, exchange.getRequest().getHeaders().getOrigin())
|
||||
Mono<UserSignupDTO> createUserMono = userService
|
||||
.createUser(user)
|
||||
.elapsed()
|
||||
.map(pair -> {
|
||||
log.debug("UserSignupCEImpl::Time taken for create user and send email: {} ms", pair.getT1());
|
||||
return pair.getT2();
|
||||
});
|
||||
|
||||
return Mono.zip(createUserAndSendEmailMono, exchange.getSession(), ReactiveSecurityContextHolder.getContext())
|
||||
return Mono.zip(createUserMono, exchange.getSession(), ReactiveSecurityContextHolder.getContext())
|
||||
.switchIfEmpty(Mono.error(new AppsmithException(AppsmithError.INTERNAL_SERVER_ERROR)))
|
||||
.flatMap(tuple -> {
|
||||
final User savedUser = tuple.getT1().getUser();
|
||||
|
|
@ -231,7 +235,8 @@ public class UserSignupCEImpl implements UserSignupCE {
|
|||
});
|
||||
}
|
||||
|
||||
public Mono<User> signupAndLoginSuper(UserSignupRequestDTO userFromRequest, ServerWebExchange exchange) {
|
||||
public Mono<User> signupAndLoginSuper(
|
||||
UserSignupRequestDTO userFromRequest, String originHeader, ServerWebExchange exchange) {
|
||||
Mono<User> userMono = userService
|
||||
.isUsersEmpty()
|
||||
.flatMap(isEmpty -> {
|
||||
|
|
@ -280,11 +285,13 @@ public class UserSignupCEImpl implements UserSignupCE {
|
|||
});
|
||||
|
||||
Mono<Void> applyEnvManagerChangesMono = envManager
|
||||
.applyChanges(Map.of(
|
||||
APPSMITH_DISABLE_TELEMETRY.name(),
|
||||
String.valueOf(!userFromRequest.isAllowCollectingAnonymousData()),
|
||||
APPSMITH_ADMIN_EMAILS.name(),
|
||||
user.getEmail()))
|
||||
.applyChanges(
|
||||
Map.of(
|
||||
APPSMITH_DISABLE_TELEMETRY.name(),
|
||||
String.valueOf(!userFromRequest.isAllowCollectingAnonymousData()),
|
||||
APPSMITH_ADMIN_EMAILS.name(),
|
||||
user.getEmail()),
|
||||
originHeader)
|
||||
// We need a non-empty value for `.elapsed` to work.
|
||||
.thenReturn(true)
|
||||
.elapsed()
|
||||
|
|
@ -331,7 +338,7 @@ public class UserSignupCEImpl implements UserSignupCE {
|
|||
});
|
||||
}
|
||||
|
||||
public Mono<Void> signupAndLoginSuperFromFormData(ServerWebExchange exchange) {
|
||||
public Mono<Void> signupAndLoginSuperFromFormData(String originHeader, ServerWebExchange exchange) {
|
||||
return exchange.getFormData()
|
||||
.map(formData -> {
|
||||
final UserSignupRequestDTO user = new UserSignupRequestDTO();
|
||||
|
|
@ -358,7 +365,7 @@ public class UserSignupCEImpl implements UserSignupCE {
|
|||
}
|
||||
return user;
|
||||
})
|
||||
.flatMap(user -> signupAndLoginSuper(user, exchange))
|
||||
.flatMap(user -> signupAndLoginSuper(user, originHeader, exchange))
|
||||
.then()
|
||||
.onErrorResume(error -> {
|
||||
String referer = exchange.getRequest().getHeaders().getFirst("referer");
|
||||
|
|
|
|||
|
|
@ -1,8 +1,9 @@
|
|||
package com.appsmith.server.solutions.ce_compatible;
|
||||
|
||||
import com.appsmith.server.notifications.EmailSender;
|
||||
import com.appsmith.server.configurations.CommonConfig;
|
||||
import com.appsmith.server.repositories.UserRepository;
|
||||
import com.appsmith.server.services.AnalyticsService;
|
||||
import com.appsmith.server.services.EmailService;
|
||||
import com.appsmith.server.services.PermissionGroupService;
|
||||
import com.appsmith.server.services.SessionUserService;
|
||||
import com.appsmith.server.services.UserService;
|
||||
|
|
@ -21,8 +22,9 @@ public class UserAndAccessManagementServiceCECompatibleImpl extends UserAndAcces
|
|||
UserRepository userRepository,
|
||||
AnalyticsService analyticsService,
|
||||
UserService userService,
|
||||
EmailSender emailSender,
|
||||
PermissionGroupPermission permissionGroupPermission) {
|
||||
PermissionGroupPermission permissionGroupPermission,
|
||||
EmailService emailService,
|
||||
CommonConfig commonConfig) {
|
||||
super(
|
||||
sessionUserService,
|
||||
permissionGroupService,
|
||||
|
|
@ -30,7 +32,8 @@ public class UserAndAccessManagementServiceCECompatibleImpl extends UserAndAcces
|
|||
userRepository,
|
||||
analyticsService,
|
||||
userService,
|
||||
emailSender,
|
||||
permissionGroupPermission);
|
||||
permissionGroupPermission,
|
||||
emailService,
|
||||
commonConfig);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,542 @@
|
|||
<!DOCTYPE html>
|
||||
<html lang="en" xmlns="http://www.w3.org/1999/xhtml">
|
||||
<head>
|
||||
<title>Reset your password for {{instanceName}}</title>
|
||||
<!--[if !mso]><!-->
|
||||
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
|
||||
<!--<![endif]-->
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1" />
|
||||
<style type="text/css">
|
||||
#outlook a {
|
||||
padding: 0;
|
||||
}
|
||||
body {
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
-webkit-text-size-adjust: 100%;
|
||||
-ms-text-size-adjust: 100%;
|
||||
}
|
||||
table,
|
||||
td {
|
||||
border-collapse: collapse;
|
||||
mso-table-lspace: 0pt;
|
||||
mso-table-rspace: 0pt;
|
||||
}
|
||||
img {
|
||||
border: 0;
|
||||
height: auto;
|
||||
line-height: 100%;
|
||||
outline: none;
|
||||
text-decoration: none;
|
||||
-ms-interpolation-mode: bicubic;
|
||||
}
|
||||
p {
|
||||
display: block;
|
||||
margin: 0;
|
||||
}
|
||||
</style>
|
||||
<!--[if mso]>
|
||||
<noscript
|
||||
><xml
|
||||
><o:OfficeDocumentSettings
|
||||
><o:AllowPNG /><o:PixelsPerInch
|
||||
>96</o:PixelsPerInch
|
||||
></o:OfficeDocumentSettings
|
||||
></xml
|
||||
></noscript
|
||||
>
|
||||
<![endif]-->
|
||||
<!--[if lte mso 11]>
|
||||
<style type="text/css">
|
||||
.ogf {
|
||||
width: 100% !important;
|
||||
}
|
||||
</style>
|
||||
<![endif]-->
|
||||
<!--[if !mso]><!-->
|
||||
<link
|
||||
href="https://fonts.googleapis.com/css?family=Inter:700"
|
||||
rel="stylesheet"
|
||||
type="text/css"
|
||||
/>
|
||||
<style type="text/css"></style>
|
||||
<!--<![endif]-->
|
||||
<style type="text/css">
|
||||
@media only screen and (min-width: 599px) {
|
||||
.xc536 {
|
||||
width: 536px !important;
|
||||
max-width: 536px;
|
||||
}
|
||||
.xc0 {
|
||||
width: 0px !important;
|
||||
max-width: 0;
|
||||
}
|
||||
.xc16 {
|
||||
width: 16px !important;
|
||||
max-width: 16px;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
<style media="screen and (min-width:599px)">
|
||||
.moz-text-html .xc536 {
|
||||
width: 536px !important;
|
||||
max-width: 536px;
|
||||
}
|
||||
.moz-text-html .xc0 {
|
||||
width: 0px !important;
|
||||
max-width: 0;
|
||||
}
|
||||
.moz-text-html .xc16 {
|
||||
width: 16px !important;
|
||||
max-width: 16px;
|
||||
}
|
||||
</style>
|
||||
<style type="text/css">
|
||||
@media only screen and (max-width: 599px) {
|
||||
table.fwm {
|
||||
width: 100% !important;
|
||||
}
|
||||
td.fwm {
|
||||
width: auto !important;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
<style type="text/css">
|
||||
u + .emailify a,
|
||||
#MessageViewBody a,
|
||||
a[x-apple-data-detectors] {
|
||||
color: inherit !important;
|
||||
text-decoration: none !important;
|
||||
font-size: inherit !important;
|
||||
font-family: inherit !important;
|
||||
font-weight: inherit !important;
|
||||
line-height: inherit !important;
|
||||
}
|
||||
span.MsoHyperlink {
|
||||
mso-style-priority: 99;
|
||||
color: inherit;
|
||||
}
|
||||
span.MsoHyperlinkFollowed {
|
||||
mso-style-priority: 99;
|
||||
color: inherit;
|
||||
}
|
||||
td.b .klaviyo-image-block {
|
||||
display: inline;
|
||||
vertical-align: middle;
|
||||
}
|
||||
@media only screen and (max-width: 599px) {
|
||||
.emailify {
|
||||
height: 100% !important;
|
||||
margin: 0 !important;
|
||||
padding: 0 !important;
|
||||
width: 100% !important;
|
||||
}
|
||||
u + .emailify .glist {
|
||||
margin-left: 1em !important;
|
||||
}
|
||||
td.x {
|
||||
padding-left: 0 !important;
|
||||
padding-right: 0 !important;
|
||||
}
|
||||
.fwm img {
|
||||
max-width: 100% !important;
|
||||
height: auto !important;
|
||||
}
|
||||
td.b.nw > table,
|
||||
td.b.nw a {
|
||||
width: auto !important;
|
||||
}
|
||||
td.stk {
|
||||
border: 0 !important;
|
||||
}
|
||||
br.sb {
|
||||
display: none !important;
|
||||
}
|
||||
.thd-1 .i-thumbnail {
|
||||
display: inline-block !important;
|
||||
height: auto !important;
|
||||
overflow: hidden !important;
|
||||
}
|
||||
.hd-1 {
|
||||
display: block !important;
|
||||
height: auto !important;
|
||||
overflow: visible !important;
|
||||
}
|
||||
.ht-1 {
|
||||
display: table !important;
|
||||
height: auto !important;
|
||||
overflow: visible !important;
|
||||
}
|
||||
.hr-1 {
|
||||
display: table-row !important;
|
||||
height: auto !important;
|
||||
overflow: visible !important;
|
||||
}
|
||||
.hc-1 {
|
||||
display: table-cell !important;
|
||||
height: auto !important;
|
||||
overflow: visible !important;
|
||||
}
|
||||
div.r.pr-16 > table > tbody > tr > td,
|
||||
div.r.pr-16 > div > table > tbody > tr > td {
|
||||
padding-right: 16px !important;
|
||||
}
|
||||
div.r.pl-16 > table > tbody > tr > td,
|
||||
div.r.pl-16 > div > table > tbody > tr > td {
|
||||
padding-left: 16px !important;
|
||||
}
|
||||
td.b.fw-1 > table {
|
||||
width: 100% !important;
|
||||
}
|
||||
td.fw-1 > table > tbody > tr > td > a {
|
||||
display: block !important;
|
||||
width: 100% !important;
|
||||
padding-left: 0 !important;
|
||||
padding-right: 0 !important;
|
||||
}
|
||||
td.b.fw-1 > table {
|
||||
width: 100% !important;
|
||||
}
|
||||
td.fw-1 > table > tbody > tr > td {
|
||||
width: 100% !important;
|
||||
padding-left: 0 !important;
|
||||
padding-right: 0 !important;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
<meta name="color-scheme" content="light dark" />
|
||||
<meta name="supported-color-schemes" content="light dark" />
|
||||
<!--[if gte mso 9]>
|
||||
<style>
|
||||
li {
|
||||
text-indent: -1em;
|
||||
}
|
||||
</style>
|
||||
<![endif]-->
|
||||
</head>
|
||||
<body
|
||||
lang="en"
|
||||
class="emailify"
|
||||
style="
|
||||
mso-line-height-rule: exactly;
|
||||
word-spacing: normal;
|
||||
background-color: #d6d6d6;
|
||||
"
|
||||
>
|
||||
<div class="bg" style="background-color: #d6d6d6">
|
||||
<!--[if mso | IE]>
|
||||
<table align="left" border="0" cellpadding="0" cellspacing="0" class="r-outlook -outlook pr-16-outlook pl-16-outlook -outlook" role="none" style="width:600px;" width="600" bgcolor="#f8f8f8"><tr><td style="line-height:0;font-size:0;mso-line-height-rule:exactly;">
|
||||
<![endif]-->
|
||||
<div
|
||||
class="r pr-16 pl-16"
|
||||
style="background-color: #f8f8f8; margin: 0px auto"
|
||||
>
|
||||
<table
|
||||
align="left"
|
||||
border="0"
|
||||
cellpadding="0"
|
||||
cellspacing="0"
|
||||
role="none"
|
||||
style="background-color: #f8f8f8; width: 100%"
|
||||
>
|
||||
<tbody>
|
||||
<tr>
|
||||
<td
|
||||
style="
|
||||
border: none;
|
||||
direction: ltr;
|
||||
font-size: 0;
|
||||
padding: 32px 32px 32px 32px;
|
||||
text-align: center;
|
||||
"
|
||||
>
|
||||
<div
|
||||
class="xc536 ogf c"
|
||||
style="
|
||||
font-size: 0;
|
||||
text-align: left;
|
||||
direction: ltr;
|
||||
display: inline-block;
|
||||
vertical-align: top;
|
||||
width: 100%;
|
||||
"
|
||||
>
|
||||
<table
|
||||
border="0"
|
||||
cellpadding="0"
|
||||
cellspacing="0"
|
||||
role="none"
|
||||
style="border-collapse: separate"
|
||||
width="600"
|
||||
>
|
||||
<tbody>
|
||||
<tr>
|
||||
<td
|
||||
style="
|
||||
background-color: #ffffff;
|
||||
border: 1px solid #f1f1f1;
|
||||
border-radius: 4px;
|
||||
vertical-align: middle;
|
||||
padding: 40px 40px;
|
||||
"
|
||||
>
|
||||
<table
|
||||
border="0"
|
||||
cellpadding="0"
|
||||
cellspacing="0"
|
||||
role="none"
|
||||
width="100%"
|
||||
>
|
||||
<tbody>
|
||||
<tr>
|
||||
<td
|
||||
align="left"
|
||||
class="i m"
|
||||
style="
|
||||
font-size: 0;
|
||||
padding: 0;
|
||||
padding-bottom: 24px;
|
||||
word-break: break-word;
|
||||
border-bottom: 1px solid #cdd5df;
|
||||
"
|
||||
>
|
||||
<table
|
||||
border="0"
|
||||
cellpadding="0"
|
||||
cellspacing="0"
|
||||
role="none"
|
||||
style="
|
||||
border-collapse: collapse;
|
||||
border-spacing: 0;
|
||||
"
|
||||
>
|
||||
<tbody>
|
||||
<tr>
|
||||
<td>
|
||||
<img
|
||||
alt=""
|
||||
height="36"
|
||||
src="https://assets.appsmith.com/appsmith-logo-no-margin.png"
|
||||
style="
|
||||
border: 0;
|
||||
display: block;
|
||||
outline: none;
|
||||
text-decoration: none;
|
||||
height: 36px;
|
||||
width: auto;
|
||||
"
|
||||
title=""
|
||||
width="200"
|
||||
/>
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td
|
||||
align="left"
|
||||
class="x m"
|
||||
style="
|
||||
font-size: 0;
|
||||
padding-top: 24px;
|
||||
padding-bottom: 16px;
|
||||
word-break: break-word;
|
||||
"
|
||||
>
|
||||
<div style="text-align: left">
|
||||
<p style="margin: 0; text-align: left">
|
||||
<span
|
||||
style="
|
||||
font-size: 14px;
|
||||
font-family: SF Pro Text, Arial,
|
||||
sans-serif;
|
||||
color: #4c5664;
|
||||
line-height: 1.43;
|
||||
font-weight: 500;
|
||||
"
|
||||
>
|
||||
Hey,
|
||||
</span>
|
||||
</p>
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td
|
||||
align="left"
|
||||
class="x m"
|
||||
style="
|
||||
font-size: 0;
|
||||
padding-bottom: 16px;
|
||||
word-break: break-word;
|
||||
"
|
||||
>
|
||||
<div style="text-align: left">
|
||||
<p style="margin: 0; text-align: left">
|
||||
<span
|
||||
style="
|
||||
font-size: 14px;
|
||||
font-family: SF Pro Text, Arial,
|
||||
sans-serif;
|
||||
color: #4c5664;
|
||||
line-height: 1.43;
|
||||
"
|
||||
>You recently requested to reset your
|
||||
Appsmith instance password. Let’s
|
||||
get you a new one in two clicks.</span
|
||||
>
|
||||
</p>
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td
|
||||
align="left"
|
||||
class="x m"
|
||||
style="
|
||||
font-size: 0;
|
||||
padding-bottom: 24px;
|
||||
word-break: break-word;
|
||||
"
|
||||
>
|
||||
<div style="text-align: left">
|
||||
<p style="margin: 0; text-align: left">
|
||||
<span
|
||||
style="
|
||||
font-size: 12px;
|
||||
font-family: SF Pro Text, Arial,
|
||||
sans-serif;
|
||||
color: #6a7585;
|
||||
line-height: 1.43;
|
||||
"
|
||||
>The link expires in two days’
|
||||
time. Better not wait.</span
|
||||
>
|
||||
</p>
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td
|
||||
align="left"
|
||||
class="b fw-1"
|
||||
style="
|
||||
font-size: 0;
|
||||
padding: 0;
|
||||
padding-bottom: 24px;
|
||||
word-break: break-word;
|
||||
border-bottom: 1px solid #cdd5df;
|
||||
"
|
||||
>
|
||||
<table
|
||||
border="0"
|
||||
cellpadding="0"
|
||||
cellspacing="0"
|
||||
role="none"
|
||||
style="
|
||||
border-collapse: separate;
|
||||
line-height: 100%;
|
||||
"
|
||||
>
|
||||
<tbody>
|
||||
<tr>
|
||||
<td
|
||||
align="center"
|
||||
bgcolor="#f86a2b"
|
||||
role="none"
|
||||
style="
|
||||
border: none;
|
||||
border-radius: 4px 4px 4px 4px;
|
||||
cursor: auto;
|
||||
mso-padding-alt: 12px 0px 12px 0px;
|
||||
background: #f86a2b;
|
||||
"
|
||||
valign="middle"
|
||||
>
|
||||
<a
|
||||
href="{{resetUrl}}"
|
||||
style="
|
||||
display: inline-block;
|
||||
background: #f86a2b;
|
||||
color: #ffffff;
|
||||
font-family: SF Pro Text, Arial,
|
||||
sans-serif;
|
||||
font-size: 14px;
|
||||
font-weight: normal;
|
||||
line-height: 100%;
|
||||
margin: 0;
|
||||
text-decoration: none;
|
||||
text-transform: none;
|
||||
padding: 12px 12px 12px 12px;
|
||||
mso-padding-alt: 0;
|
||||
border-radius: 4px 4px 4px 4px;
|
||||
"
|
||||
target="_blank"
|
||||
>
|
||||
<span
|
||||
style="
|
||||
font-size: 14px;
|
||||
font-family: SF Pro Text, Arial,
|
||||
sans-serif;
|
||||
color: #ffffff;
|
||||
line-height: 1.43;
|
||||
"
|
||||
>Set a new password now</span
|
||||
></a
|
||||
>
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td
|
||||
align="left"
|
||||
class="x m"
|
||||
style="
|
||||
font-size: 0;
|
||||
padding-top: 24px;
|
||||
word-break: break-word;
|
||||
"
|
||||
>
|
||||
<div style="text-align: left">
|
||||
<p style="margin: 0; text-align: left">
|
||||
<span
|
||||
style="
|
||||
font-size: 12px;
|
||||
font-family: SF Pro Text, Arial,
|
||||
sans-serif;
|
||||
font-weight: 400;
|
||||
color: #6a7585;
|
||||
line-height: 1.43;
|
||||
"
|
||||
>1390, Market Street, Suite 200, San
|
||||
Francisco, California 94102, United
|
||||
States</span
|
||||
>
|
||||
</p>
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
<!--[if mso | IE]>
|
||||
</td></tr></table>
|
||||
<![endif]-->
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
|
|
@ -0,0 +1,545 @@
|
|||
<!DOCTYPE html>
|
||||
<html lang="en" xmlns="http://www.w3.org/1999/xhtml">
|
||||
<head>
|
||||
<title>You're invited to the appsmith instance {{instanceName}}</title>
|
||||
<!--[if !mso]><!-->
|
||||
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
|
||||
<!--<![endif]-->
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1" />
|
||||
<style type="text/css">
|
||||
#outlook a {
|
||||
padding: 0;
|
||||
}
|
||||
body {
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
-webkit-text-size-adjust: 100%;
|
||||
-ms-text-size-adjust: 100%;
|
||||
}
|
||||
table,
|
||||
td {
|
||||
border-collapse: collapse;
|
||||
mso-table-lspace: 0pt;
|
||||
mso-table-rspace: 0pt;
|
||||
}
|
||||
img {
|
||||
border: 0;
|
||||
height: auto;
|
||||
line-height: 100%;
|
||||
outline: none;
|
||||
text-decoration: none;
|
||||
-ms-interpolation-mode: bicubic;
|
||||
}
|
||||
p {
|
||||
display: block;
|
||||
margin: 0;
|
||||
}
|
||||
</style>
|
||||
<!--[if mso]>
|
||||
<noscript
|
||||
><xml
|
||||
><o:OfficeDocumentSettings
|
||||
><o:AllowPNG /><o:PixelsPerInch
|
||||
>96</o:PixelsPerInch
|
||||
></o:OfficeDocumentSettings
|
||||
></xml
|
||||
></noscript
|
||||
>
|
||||
<![endif]-->
|
||||
<!--[if lte mso 11]>
|
||||
<style type="text/css">
|
||||
.ogf {
|
||||
width: 100% !important;
|
||||
}
|
||||
</style>
|
||||
<![endif]-->
|
||||
<!--[if !mso]><!-->
|
||||
<link
|
||||
href="https://fonts.googleapis.com/css?family=Inter:700"
|
||||
rel="stylesheet"
|
||||
type="text/css"
|
||||
/>
|
||||
<style type="text/css"></style>
|
||||
<!--<![endif]-->
|
||||
<style type="text/css">
|
||||
@media only screen and (min-width: 599px) {
|
||||
.xc536 {
|
||||
width: 536px !important;
|
||||
max-width: 536px;
|
||||
}
|
||||
.xc0 {
|
||||
width: 0px !important;
|
||||
max-width: 0;
|
||||
}
|
||||
.xc16 {
|
||||
width: 16px !important;
|
||||
max-width: 16px;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
<style media="screen and (min-width:599px)">
|
||||
.moz-text-html .xc536 {
|
||||
width: 536px !important;
|
||||
max-width: 536px;
|
||||
}
|
||||
.moz-text-html .xc0 {
|
||||
width: 0px !important;
|
||||
max-width: 0;
|
||||
}
|
||||
.moz-text-html .xc16 {
|
||||
width: 16px !important;
|
||||
max-width: 16px;
|
||||
}
|
||||
</style>
|
||||
<style type="text/css">
|
||||
@media only screen and (max-width: 599px) {
|
||||
table.fwm {
|
||||
width: 100% !important;
|
||||
}
|
||||
td.fwm {
|
||||
width: auto !important;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
<style type="text/css">
|
||||
u + .emailify a,
|
||||
#MessageViewBody a,
|
||||
a[x-apple-data-detectors] {
|
||||
color: inherit !important;
|
||||
text-decoration: none !important;
|
||||
font-size: inherit !important;
|
||||
font-family: inherit !important;
|
||||
font-weight: inherit !important;
|
||||
line-height: inherit !important;
|
||||
}
|
||||
span.MsoHyperlink {
|
||||
mso-style-priority: 99;
|
||||
color: inherit;
|
||||
}
|
||||
span.MsoHyperlinkFollowed {
|
||||
mso-style-priority: 99;
|
||||
color: inherit;
|
||||
}
|
||||
td.b .klaviyo-image-block {
|
||||
display: inline;
|
||||
vertical-align: middle;
|
||||
}
|
||||
@media only screen and (max-width: 599px) {
|
||||
.emailify {
|
||||
height: 100% !important;
|
||||
margin: 0 !important;
|
||||
padding: 0 !important;
|
||||
width: 100% !important;
|
||||
}
|
||||
u + .emailify .glist {
|
||||
margin-left: 1em !important;
|
||||
}
|
||||
td.x {
|
||||
padding-left: 0 !important;
|
||||
padding-right: 0 !important;
|
||||
}
|
||||
.fwm img {
|
||||
max-width: 100% !important;
|
||||
height: auto !important;
|
||||
}
|
||||
td.b.nw > table,
|
||||
td.b.nw a {
|
||||
width: auto !important;
|
||||
}
|
||||
td.stk {
|
||||
border: 0 !important;
|
||||
}
|
||||
br.sb {
|
||||
display: none !important;
|
||||
}
|
||||
.thd-1 .i-thumbnail {
|
||||
display: inline-block !important;
|
||||
height: auto !important;
|
||||
overflow: hidden !important;
|
||||
}
|
||||
.hd-1 {
|
||||
display: block !important;
|
||||
height: auto !important;
|
||||
overflow: visible !important;
|
||||
}
|
||||
.ht-1 {
|
||||
display: table !important;
|
||||
height: auto !important;
|
||||
overflow: visible !important;
|
||||
}
|
||||
.hr-1 {
|
||||
display: table-row !important;
|
||||
height: auto !important;
|
||||
overflow: visible !important;
|
||||
}
|
||||
.hc-1 {
|
||||
display: table-cell !important;
|
||||
height: auto !important;
|
||||
overflow: visible !important;
|
||||
}
|
||||
div.r.pr-16 > table > tbody > tr > td,
|
||||
div.r.pr-16 > div > table > tbody > tr > td {
|
||||
padding-right: 16px !important;
|
||||
}
|
||||
div.r.pl-16 > table > tbody > tr > td,
|
||||
div.r.pl-16 > div > table > tbody > tr > td {
|
||||
padding-left: 16px !important;
|
||||
}
|
||||
td.b.fw-1 > table {
|
||||
width: 100% !important;
|
||||
}
|
||||
td.fw-1 > table > tbody > tr > td > a {
|
||||
display: block !important;
|
||||
width: 100% !important;
|
||||
padding-left: 0 !important;
|
||||
padding-right: 0 !important;
|
||||
}
|
||||
td.b.fw-1 > table {
|
||||
width: 100% !important;
|
||||
}
|
||||
td.fw-1 > table > tbody > tr > td {
|
||||
width: 100% !important;
|
||||
padding-left: 0 !important;
|
||||
padding-right: 0 !important;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
<meta name="color-scheme" content="light dark" />
|
||||
<meta name="supported-color-schemes" content="light dark" />
|
||||
<!--[if gte mso 9]>
|
||||
<style>
|
||||
li {
|
||||
text-indent: -1em;
|
||||
}
|
||||
</style>
|
||||
<![endif]-->
|
||||
</head>
|
||||
<body
|
||||
lang="en"
|
||||
class="emailify"
|
||||
style="
|
||||
mso-line-height-rule: exactly;
|
||||
word-spacing: normal;
|
||||
background-color: #d6d6d6;
|
||||
"
|
||||
>
|
||||
<div class="bg" style="background-color: #d6d6d6">
|
||||
<!--[if mso | IE]>
|
||||
<table align="left" border="0" cellpadding="0" cellspacing="0" class="r-outlook -outlook pr-16-outlook pl-16-outlook -outlook" role="none" style="width:600px;" width="600" bgcolor="#f8f8f8"><tr><td style="line-height:0;font-size:0;mso-line-height-rule:exactly;">
|
||||
<![endif]-->
|
||||
<div
|
||||
class="r pr-16 pl-16"
|
||||
style="background-color: #f8f8f8; margin: 0px auto"
|
||||
>
|
||||
<table
|
||||
align="left"
|
||||
border="0"
|
||||
cellpadding="0"
|
||||
cellspacing="0"
|
||||
role="none"
|
||||
style="background-color: #f8f8f8; width: 100%"
|
||||
>
|
||||
<tbody>
|
||||
<tr>
|
||||
<td
|
||||
style="
|
||||
border: none;
|
||||
direction: ltr;
|
||||
font-size: 0;
|
||||
padding: 32px 32px 32px 32px;
|
||||
text-align: center;
|
||||
"
|
||||
>
|
||||
<div
|
||||
class="xc536 ogf c"
|
||||
style="
|
||||
font-size: 0;
|
||||
text-align: left;
|
||||
direction: ltr;
|
||||
display: inline-block;
|
||||
vertical-align: top;
|
||||
width: 100%;
|
||||
"
|
||||
>
|
||||
<table
|
||||
border="0"
|
||||
cellpadding="0"
|
||||
cellspacing="0"
|
||||
role="none"
|
||||
style="border-collapse: separate"
|
||||
width="600"
|
||||
>
|
||||
<tbody>
|
||||
<tr>
|
||||
<td
|
||||
style="
|
||||
background-color: #ffffff;
|
||||
border: 1px solid #f1f1f1;
|
||||
border-radius: 4px;
|
||||
vertical-align: top;
|
||||
padding: 40px 40px;
|
||||
"
|
||||
>
|
||||
<table
|
||||
border="0"
|
||||
cellpadding="0"
|
||||
cellspacing="0"
|
||||
role="none"
|
||||
width="100%"
|
||||
>
|
||||
<tbody>
|
||||
<tr>
|
||||
<td
|
||||
align="left"
|
||||
class="i m"
|
||||
style="
|
||||
font-size: 0;
|
||||
padding: 0;
|
||||
padding-bottom: 24px;
|
||||
word-break: break-word;
|
||||
border-bottom: 1px solid #cdd5df;
|
||||
"
|
||||
>
|
||||
<table
|
||||
border="0"
|
||||
cellpadding="0"
|
||||
cellspacing="0"
|
||||
role="none"
|
||||
style="
|
||||
border-collapse: collapse;
|
||||
border-spacing: 0;
|
||||
"
|
||||
>
|
||||
<tbody>
|
||||
<tr>
|
||||
<td>
|
||||
<img
|
||||
alt=""
|
||||
height="36"
|
||||
src="https://assets.appsmith.com/appsmith-logo-no-margin.png"
|
||||
style="
|
||||
border: 0;
|
||||
display: block;
|
||||
outline: none;
|
||||
text-decoration: none;
|
||||
height: 36px;
|
||||
width: auto;
|
||||
"
|
||||
title=""
|
||||
width="200"
|
||||
/>
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td
|
||||
align="left"
|
||||
class="x m"
|
||||
style="
|
||||
font-size: 0;
|
||||
padding-top: 24px;
|
||||
padding-bottom: 16px;
|
||||
word-break: break-word;
|
||||
"
|
||||
>
|
||||
<div style="text-align: left">
|
||||
<p style="margin: 0; text-align: left">
|
||||
<span
|
||||
style="
|
||||
font-size: 14px;
|
||||
font-family: SF Pro Text, Arial,
|
||||
sans-serif;
|
||||
color: #4c5664;
|
||||
line-height: 1.43;
|
||||
font-weight: 500;
|
||||
"
|
||||
>
|
||||
Hey,
|
||||
</span>
|
||||
</p>
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td
|
||||
align="left"
|
||||
class="x m"
|
||||
style="
|
||||
font-size: 0;
|
||||
padding-bottom: 16px;
|
||||
word-break: break-word;
|
||||
"
|
||||
>
|
||||
<div style="text-align: left">
|
||||
<p style="margin: 0; text-align: left">
|
||||
<span
|
||||
style="
|
||||
font-size: 14px;
|
||||
font-family: SF Pro Text, Arial,
|
||||
sans-serif;
|
||||
color: #4c5664;
|
||||
line-height: 1.43;
|
||||
"
|
||||
>{{inviterFirstName}} has invited you to
|
||||
the Appsmith instance
|
||||
<b>{{instanceName}}</b></span
|
||||
>
|
||||
</p>
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td
|
||||
align="left"
|
||||
class="x m"
|
||||
style="
|
||||
font-size: 0;
|
||||
padding-bottom: 24px;
|
||||
word-break: break-word;
|
||||
"
|
||||
>
|
||||
<div style="text-align: left">
|
||||
<p style="margin: 0; text-align: left">
|
||||
<span
|
||||
style="
|
||||
font-size: 14px;
|
||||
font-family: SF Pro Text, Arial,
|
||||
sans-serif;
|
||||
font-weight: 400;
|
||||
color: #4c5664;
|
||||
line-height: 1.43;
|
||||
"
|
||||
>Join your Appsmith instance to get
|
||||
access to fast, usable, beautiful
|
||||
apps.</span
|
||||
>
|
||||
</p>
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td
|
||||
align="left"
|
||||
class="b fw-1"
|
||||
style="
|
||||
font-size: 0;
|
||||
padding: 0;
|
||||
padding-bottom: 24px;
|
||||
word-break: break-word;
|
||||
border-bottom: 1px solid #cdd5df;
|
||||
"
|
||||
>
|
||||
<table
|
||||
border="0"
|
||||
cellpadding="0"
|
||||
cellspacing="0"
|
||||
role="none"
|
||||
style="
|
||||
border-collapse: separate;
|
||||
line-height: 100%;
|
||||
"
|
||||
>
|
||||
<tbody>
|
||||
<tr>
|
||||
<td
|
||||
align="center"
|
||||
bgcolor="#f86a2b"
|
||||
role="none"
|
||||
style="
|
||||
border: none;
|
||||
border-radius: 4px 4px 4px 4px;
|
||||
cursor: auto;
|
||||
mso-padding-alt: 12px 0px 12px 0px;
|
||||
background: #f86a2b;
|
||||
color: #ffffff;
|
||||
"
|
||||
valign="middle"
|
||||
>
|
||||
<a
|
||||
href="{{primaryLinkUrl}}"
|
||||
style="
|
||||
display: inline-block;
|
||||
font-family: SF Pro Text, Arial,
|
||||
sans-serif;
|
||||
font-size: 14px;
|
||||
background: #f86a2b;
|
||||
color: #ffffff;
|
||||
font-weight: normal;
|
||||
line-height: 100%;
|
||||
margin: 0;
|
||||
text-decoration: none;
|
||||
text-transform: none;
|
||||
padding: 12px 12px 12px 12px;
|
||||
mso-padding-alt: 0;
|
||||
border-radius: 4px 4px 4px 4px;
|
||||
"
|
||||
target="_blank"
|
||||
>
|
||||
<span
|
||||
style="
|
||||
font-size: 14px;
|
||||
font-family: SF Pro Text, Arial,
|
||||
sans-serif;
|
||||
line-height: 1.43;
|
||||
color: #ffffff;
|
||||
"
|
||||
>{{primaryLinkText}}</span
|
||||
></a
|
||||
>
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td
|
||||
align="left"
|
||||
class="x m"
|
||||
style="
|
||||
font-size: 0;
|
||||
padding-top: 24px;
|
||||
word-break: break-word;
|
||||
"
|
||||
>
|
||||
<div style="text-align: left">
|
||||
<p style="margin: 0; text-align: left">
|
||||
<span
|
||||
style="
|
||||
font-size: 12px;
|
||||
font-family: SF Pro Text, Arial,
|
||||
sans-serif;
|
||||
font-weight: 400;
|
||||
color: #6a7585;
|
||||
line-height: 1.43;
|
||||
"
|
||||
>1390, Market Street, Suite 200, San
|
||||
Francisco, California 94102, United
|
||||
States</span
|
||||
>
|
||||
</p>
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
<!--[if mso | IE]>
|
||||
</td></tr></table>
|
||||
<![endif]-->
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
|
|
@ -0,0 +1,547 @@
|
|||
<!DOCTYPE html>
|
||||
<html lang="en" xmlns="http://www.w3.org/1999/xhtml">
|
||||
<head>
|
||||
<title>You're invited to the workspace {{inviterWorkspaceName}}</title>
|
||||
<!--[if !mso]><!-->
|
||||
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
|
||||
<!--<![endif]-->
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1" />
|
||||
<style type="text/css">
|
||||
#outlook a {
|
||||
padding: 0;
|
||||
}
|
||||
body {
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
-webkit-text-size-adjust: 100%;
|
||||
-ms-text-size-adjust: 100%;
|
||||
}
|
||||
table,
|
||||
td {
|
||||
border-collapse: collapse;
|
||||
mso-table-lspace: 0pt;
|
||||
mso-table-rspace: 0pt;
|
||||
}
|
||||
img {
|
||||
border: 0;
|
||||
height: auto;
|
||||
line-height: 100%;
|
||||
outline: none;
|
||||
text-decoration: none;
|
||||
-ms-interpolation-mode: bicubic;
|
||||
}
|
||||
p {
|
||||
display: block;
|
||||
margin: 0;
|
||||
}
|
||||
</style>
|
||||
<!--[if mso]>
|
||||
<noscript
|
||||
><xml
|
||||
><o:OfficeDocumentSettings
|
||||
><o:AllowPNG /><o:PixelsPerInch
|
||||
>96</o:PixelsPerInch
|
||||
></o:OfficeDocumentSettings
|
||||
></xml
|
||||
></noscript
|
||||
>
|
||||
<![endif]-->
|
||||
<!--[if lte mso 11]>
|
||||
<style type="text/css">
|
||||
.ogf {
|
||||
width: 100% !important;
|
||||
}
|
||||
</style>
|
||||
<![endif]-->
|
||||
<!--[if !mso]><!-->
|
||||
<link
|
||||
href="https://fonts.googleapis.com/css?family=Inter:700"
|
||||
rel="stylesheet"
|
||||
type="text/css"
|
||||
/>
|
||||
<style type="text/css"></style>
|
||||
<!--<![endif]-->
|
||||
<style type="text/css">
|
||||
@media only screen and (min-width: 599px) {
|
||||
.xc536 {
|
||||
width: 536px !important;
|
||||
max-width: 536px;
|
||||
}
|
||||
.xc0 {
|
||||
width: 0px !important;
|
||||
max-width: 0;
|
||||
}
|
||||
.xc16 {
|
||||
width: 16px !important;
|
||||
max-width: 16px;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
<style media="screen and (min-width:599px)">
|
||||
.moz-text-html .xc536 {
|
||||
width: 536px !important;
|
||||
max-width: 536px;
|
||||
}
|
||||
.moz-text-html .xc0 {
|
||||
width: 0px !important;
|
||||
max-width: 0;
|
||||
}
|
||||
.moz-text-html .xc16 {
|
||||
width: 16px !important;
|
||||
max-width: 16px;
|
||||
}
|
||||
</style>
|
||||
<style type="text/css">
|
||||
@media only screen and (max-width: 599px) {
|
||||
table.fwm {
|
||||
width: 100% !important;
|
||||
}
|
||||
td.fwm {
|
||||
width: auto !important;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
<style type="text/css">
|
||||
u + .emailify a,
|
||||
#MessageViewBody a,
|
||||
a[x-apple-data-detectors] {
|
||||
color: inherit !important;
|
||||
text-decoration: none !important;
|
||||
font-size: inherit !important;
|
||||
font-family: inherit !important;
|
||||
font-weight: inherit !important;
|
||||
line-height: inherit !important;
|
||||
}
|
||||
span.MsoHyperlink {
|
||||
mso-style-priority: 99;
|
||||
color: inherit;
|
||||
}
|
||||
span.MsoHyperlinkFollowed {
|
||||
mso-style-priority: 99;
|
||||
color: inherit;
|
||||
}
|
||||
td.b .klaviyo-image-block {
|
||||
display: inline;
|
||||
vertical-align: middle;
|
||||
}
|
||||
@media only screen and (max-width: 599px) {
|
||||
.emailify {
|
||||
height: 100% !important;
|
||||
margin: 0 !important;
|
||||
padding: 0 !important;
|
||||
width: 100% !important;
|
||||
}
|
||||
u + .emailify .glist {
|
||||
margin-left: 1em !important;
|
||||
}
|
||||
td.x {
|
||||
padding-left: 0 !important;
|
||||
padding-right: 0 !important;
|
||||
}
|
||||
.fwm img {
|
||||
max-width: 100% !important;
|
||||
height: auto !important;
|
||||
}
|
||||
td.b.nw > table,
|
||||
td.b.nw a {
|
||||
width: auto !important;
|
||||
}
|
||||
td.stk {
|
||||
border: 0 !important;
|
||||
}
|
||||
br.sb {
|
||||
display: none !important;
|
||||
}
|
||||
.thd-1 .i-thumbnail {
|
||||
display: inline-block !important;
|
||||
height: auto !important;
|
||||
overflow: hidden !important;
|
||||
}
|
||||
.hd-1 {
|
||||
display: block !important;
|
||||
height: auto !important;
|
||||
overflow: visible !important;
|
||||
}
|
||||
.ht-1 {
|
||||
display: table !important;
|
||||
height: auto !important;
|
||||
overflow: visible !important;
|
||||
}
|
||||
.hr-1 {
|
||||
display: table-row !important;
|
||||
height: auto !important;
|
||||
overflow: visible !important;
|
||||
}
|
||||
.hc-1 {
|
||||
display: table-cell !important;
|
||||
height: auto !important;
|
||||
overflow: visible !important;
|
||||
}
|
||||
div.r.pr-16 > table > tbody > tr > td,
|
||||
div.r.pr-16 > div > table > tbody > tr > td {
|
||||
padding-right: 16px !important;
|
||||
}
|
||||
div.r.pl-16 > table > tbody > tr > td,
|
||||
div.r.pl-16 > div > table > tbody > tr > td {
|
||||
padding-left: 16px !important;
|
||||
}
|
||||
td.b.fw-1 > table {
|
||||
width: 100% !important;
|
||||
}
|
||||
td.fw-1 > table > tbody > tr > td > a {
|
||||
display: block !important;
|
||||
width: 100% !important;
|
||||
padding-left: 0 !important;
|
||||
padding-right: 0 !important;
|
||||
}
|
||||
td.b.fw-1 > table {
|
||||
width: 100% !important;
|
||||
}
|
||||
td.fw-1 > table > tbody > tr > td {
|
||||
width: 100% !important;
|
||||
padding-left: 0 !important;
|
||||
padding-right: 0 !important;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
<meta name="color-scheme" content="light dark" />
|
||||
<meta name="supported-color-schemes" content="light dark" />
|
||||
<!--[if gte mso 9]>
|
||||
<style>
|
||||
li {
|
||||
text-indent: -1em;
|
||||
}
|
||||
</style>
|
||||
<![endif]-->
|
||||
</head>
|
||||
<body
|
||||
lang="en"
|
||||
class="emailify"
|
||||
style="
|
||||
mso-line-height-rule: exactly;
|
||||
word-spacing: normal;
|
||||
background-color: #d6d6d6;
|
||||
"
|
||||
>
|
||||
<div class="bg" style="background-color: #d6d6d6">
|
||||
<!--[if mso | IE]>
|
||||
<table align="left" border="0" cellpadding="0" cellspacing="0" class="r-outlook -outlook pr-16-outlook pl-16-outlook -outlook" role="none" style="width:600px;" width="600" bgcolor="#f8f8f8"><tr><td style="line-height:0;font-size:0;mso-line-height-rule:exactly;">
|
||||
<![endif]-->
|
||||
<div
|
||||
class="r pr-16 pl-16"
|
||||
style="background-color: #f8f8f8; margin: 0px auto"
|
||||
>
|
||||
<table
|
||||
align="left"
|
||||
border="0"
|
||||
cellpadding="0"
|
||||
cellspacing="0"
|
||||
role="none"
|
||||
style="background-color: #f8f8f8; width: 100%"
|
||||
>
|
||||
<tbody>
|
||||
<tr>
|
||||
<td
|
||||
style="
|
||||
border: none;
|
||||
direction: ltr;
|
||||
font-size: 0;
|
||||
padding: 32px 32px 32px 32px;
|
||||
text-align: center;
|
||||
"
|
||||
>
|
||||
<div
|
||||
class="xc536 ogf c"
|
||||
style="
|
||||
font-size: 0;
|
||||
text-align: left;
|
||||
direction: ltr;
|
||||
display: inline-block;
|
||||
vertical-align: top;
|
||||
width: 100%;
|
||||
"
|
||||
>
|
||||
<table
|
||||
border="0"
|
||||
cellpadding="0"
|
||||
cellspacing="0"
|
||||
role="none"
|
||||
style="border-collapse: separate"
|
||||
width="600"
|
||||
>
|
||||
<tbody>
|
||||
<tr>
|
||||
<td
|
||||
style="
|
||||
background-color: #ffffff;
|
||||
border: 1px solid #f1f1f1;
|
||||
border-radius: 4px;
|
||||
vertical-align: top;
|
||||
padding: 40px 40px;
|
||||
"
|
||||
>
|
||||
<table
|
||||
border="0"
|
||||
cellpadding="0"
|
||||
cellspacing="0"
|
||||
role="none"
|
||||
width="100%"
|
||||
>
|
||||
<tbody>
|
||||
<tr>
|
||||
<td
|
||||
align="left"
|
||||
class="i m"
|
||||
style="
|
||||
font-size: 0;
|
||||
padding: 0;
|
||||
padding-bottom: 24px;
|
||||
word-break: break-word;
|
||||
border-bottom: 1px solid #cdd5df;
|
||||
"
|
||||
>
|
||||
<table
|
||||
border="0"
|
||||
cellpadding="0"
|
||||
cellspacing="0"
|
||||
role="none"
|
||||
style="
|
||||
border-collapse: collapse;
|
||||
border-spacing: 0;
|
||||
"
|
||||
>
|
||||
<tbody>
|
||||
<tr>
|
||||
<td>
|
||||
<img
|
||||
alt=""
|
||||
height="36"
|
||||
src="https://assets.appsmith.com/appsmith-logo-no-margin.png"
|
||||
style="
|
||||
border: 0;
|
||||
display: block;
|
||||
outline: none;
|
||||
text-decoration: none;
|
||||
height: 36px;
|
||||
width: auto;
|
||||
"
|
||||
title=""
|
||||
width="200"
|
||||
/>
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td
|
||||
align="left"
|
||||
class="x m"
|
||||
style="
|
||||
font-size: 0;
|
||||
padding-top: 24px;
|
||||
padding-bottom: 16px;
|
||||
word-break: break-word;
|
||||
"
|
||||
>
|
||||
<div style="text-align: left">
|
||||
<p style="margin: 0; text-align: left">
|
||||
<span
|
||||
style="
|
||||
font-size: 14px;
|
||||
font-family: SF Pro Text, Arial,
|
||||
sans-serif;
|
||||
color: #4c5664;
|
||||
line-height: 1.43;
|
||||
font-weight: 500;
|
||||
"
|
||||
>
|
||||
Hey,
|
||||
</span>
|
||||
</p>
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td
|
||||
align="left"
|
||||
class="x m"
|
||||
style="
|
||||
font-size: 0;
|
||||
padding-bottom: 16px;
|
||||
word-break: break-word;
|
||||
"
|
||||
>
|
||||
<div style="text-align: left">
|
||||
<p style="margin: 0; text-align: left">
|
||||
<span
|
||||
style="
|
||||
font-size: 14px;
|
||||
font-family: SF Pro Text, Arial,
|
||||
sans-serif;
|
||||
color: #4c5664;
|
||||
line-height: 1.43;
|
||||
"
|
||||
>{{inviterFirstName}} has invited you as
|
||||
<b>{{role}}</b> to the Appsmith
|
||||
workspace
|
||||
<b>{{inviterWorkspaceName}}</b></span
|
||||
>
|
||||
</p>
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td
|
||||
align="left"
|
||||
class="x m"
|
||||
style="
|
||||
font-size: 0;
|
||||
padding-bottom: 24px;
|
||||
word-break: break-word;
|
||||
"
|
||||
>
|
||||
<div style="text-align: left">
|
||||
<p style="margin: 0; text-align: left">
|
||||
<span
|
||||
style="
|
||||
font-size: 14px;
|
||||
font-family: SF Pro Text, Arial,
|
||||
sans-serif;
|
||||
font-weight: 400;
|
||||
color: #4c5664;
|
||||
line-height: 1.43;
|
||||
"
|
||||
>Join your Appsmith workspace to get
|
||||
access to fast, usable, beautiful
|
||||
apps.</span
|
||||
>
|
||||
</p>
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td
|
||||
align="left"
|
||||
class="b fw-1"
|
||||
style="
|
||||
font-size: 0;
|
||||
padding: 0;
|
||||
padding-bottom: 24px;
|
||||
word-break: break-word;
|
||||
border-bottom: 1px solid #cdd5df;
|
||||
"
|
||||
>
|
||||
<table
|
||||
border="0"
|
||||
cellpadding="0"
|
||||
cellspacing="0"
|
||||
role="none"
|
||||
style="
|
||||
border-collapse: separate;
|
||||
line-height: 100%;
|
||||
"
|
||||
>
|
||||
<tbody>
|
||||
<tr>
|
||||
<td
|
||||
align="center"
|
||||
bgcolor="#f86a2b"
|
||||
role="none"
|
||||
style="
|
||||
border: none;
|
||||
border-radius: 4px 4px 4px 4px;
|
||||
cursor: auto;
|
||||
mso-padding-alt: 12px 0px 12px 0px;
|
||||
background: #f86a2b;
|
||||
color: #ffffff;
|
||||
"
|
||||
valign="middle"
|
||||
>
|
||||
<a
|
||||
href="{{primaryLinkUrl}}"
|
||||
style="
|
||||
display: inline-block;
|
||||
font-family: SF Pro Text, Arial,
|
||||
sans-serif;
|
||||
font-size: 14px;
|
||||
background: #f86a2b;
|
||||
color: #ffffff;
|
||||
font-weight: normal;
|
||||
line-height: 100%;
|
||||
margin: 0;
|
||||
text-decoration: none;
|
||||
text-transform: none;
|
||||
padding: 12px 12px 12px 12px;
|
||||
mso-padding-alt: 0;
|
||||
border-radius: 4px 4px 4px 4px;
|
||||
"
|
||||
target="_blank"
|
||||
>
|
||||
<span
|
||||
style="
|
||||
font-size: 14px;
|
||||
font-family: SF Pro Text, Arial,
|
||||
sans-serif;
|
||||
line-height: 1.43;
|
||||
color: #ffffff;
|
||||
"
|
||||
>Go to your Appsmith
|
||||
workspace</span
|
||||
></a
|
||||
>
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td
|
||||
align="left"
|
||||
class="x m"
|
||||
style="
|
||||
font-size: 0;
|
||||
padding-top: 24px;
|
||||
word-break: break-word;
|
||||
"
|
||||
>
|
||||
<div style="text-align: left">
|
||||
<p style="margin: 0; text-align: left">
|
||||
<span
|
||||
style="
|
||||
font-size: 12px;
|
||||
font-family: SF Pro Text, Arial,
|
||||
sans-serif;
|
||||
font-weight: 400;
|
||||
color: #6a7585;
|
||||
line-height: 1.43;
|
||||
"
|
||||
>1390, Market Street, Suite 200, San
|
||||
Francisco, California 94102, United
|
||||
States</span
|
||||
>
|
||||
</p>
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
<!--[if mso | IE]>
|
||||
</td></tr></table>
|
||||
<![endif]-->
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
|
|
@ -0,0 +1,547 @@
|
|||
<!DOCTYPE html>
|
||||
<html lang="en" xmlns="http://www.w3.org/1999/xhtml">
|
||||
<head>
|
||||
<title>You're invited to the workspace {{inviterWorkspaceName}}</title>
|
||||
<!--[if !mso]><!-->
|
||||
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
|
||||
<!--<![endif]-->
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1" />
|
||||
<style type="text/css">
|
||||
#outlook a {
|
||||
padding: 0;
|
||||
}
|
||||
body {
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
-webkit-text-size-adjust: 100%;
|
||||
-ms-text-size-adjust: 100%;
|
||||
}
|
||||
table,
|
||||
td {
|
||||
border-collapse: collapse;
|
||||
mso-table-lspace: 0pt;
|
||||
mso-table-rspace: 0pt;
|
||||
}
|
||||
img {
|
||||
border: 0;
|
||||
height: auto;
|
||||
line-height: 100%;
|
||||
outline: none;
|
||||
text-decoration: none;
|
||||
-ms-interpolation-mode: bicubic;
|
||||
}
|
||||
p {
|
||||
display: block;
|
||||
margin: 0;
|
||||
}
|
||||
</style>
|
||||
<!--[if mso]>
|
||||
<noscript
|
||||
><xml
|
||||
><o:OfficeDocumentSettings
|
||||
><o:AllowPNG /><o:PixelsPerInch
|
||||
>96</o:PixelsPerInch
|
||||
></o:OfficeDocumentSettings
|
||||
></xml
|
||||
></noscript
|
||||
>
|
||||
<![endif]-->
|
||||
<!--[if lte mso 11]>
|
||||
<style type="text/css">
|
||||
.ogf {
|
||||
width: 100% !important;
|
||||
}
|
||||
</style>
|
||||
<![endif]-->
|
||||
<!--[if !mso]><!-->
|
||||
<link
|
||||
href="https://fonts.googleapis.com/css?family=Inter:700"
|
||||
rel="stylesheet"
|
||||
type="text/css"
|
||||
/>
|
||||
<style type="text/css"></style>
|
||||
<!--<![endif]-->
|
||||
<style type="text/css">
|
||||
@media only screen and (min-width: 599px) {
|
||||
.xc536 {
|
||||
width: 536px !important;
|
||||
max-width: 536px;
|
||||
}
|
||||
.xc0 {
|
||||
width: 0px !important;
|
||||
max-width: 0;
|
||||
}
|
||||
.xc16 {
|
||||
width: 16px !important;
|
||||
max-width: 16px;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
<style media="screen and (min-width:599px)">
|
||||
.moz-text-html .xc536 {
|
||||
width: 536px !important;
|
||||
max-width: 536px;
|
||||
}
|
||||
.moz-text-html .xc0 {
|
||||
width: 0px !important;
|
||||
max-width: 0;
|
||||
}
|
||||
.moz-text-html .xc16 {
|
||||
width: 16px !important;
|
||||
max-width: 16px;
|
||||
}
|
||||
</style>
|
||||
<style type="text/css">
|
||||
@media only screen and (max-width: 599px) {
|
||||
table.fwm {
|
||||
width: 100% !important;
|
||||
}
|
||||
td.fwm {
|
||||
width: auto !important;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
<style type="text/css">
|
||||
u + .emailify a,
|
||||
#MessageViewBody a,
|
||||
a[x-apple-data-detectors] {
|
||||
color: inherit !important;
|
||||
text-decoration: none !important;
|
||||
font-size: inherit !important;
|
||||
font-family: inherit !important;
|
||||
font-weight: inherit !important;
|
||||
line-height: inherit !important;
|
||||
}
|
||||
span.MsoHyperlink {
|
||||
mso-style-priority: 99;
|
||||
color: inherit;
|
||||
}
|
||||
span.MsoHyperlinkFollowed {
|
||||
mso-style-priority: 99;
|
||||
color: inherit;
|
||||
}
|
||||
td.b .klaviyo-image-block {
|
||||
display: inline;
|
||||
vertical-align: middle;
|
||||
}
|
||||
@media only screen and (max-width: 599px) {
|
||||
.emailify {
|
||||
height: 100% !important;
|
||||
margin: 0 !important;
|
||||
padding: 0 !important;
|
||||
width: 100% !important;
|
||||
}
|
||||
u + .emailify .glist {
|
||||
margin-left: 1em !important;
|
||||
}
|
||||
td.x {
|
||||
padding-left: 0 !important;
|
||||
padding-right: 0 !important;
|
||||
}
|
||||
.fwm img {
|
||||
max-width: 100% !important;
|
||||
height: auto !important;
|
||||
}
|
||||
td.b.nw > table,
|
||||
td.b.nw a {
|
||||
width: auto !important;
|
||||
}
|
||||
td.stk {
|
||||
border: 0 !important;
|
||||
}
|
||||
br.sb {
|
||||
display: none !important;
|
||||
}
|
||||
.thd-1 .i-thumbnail {
|
||||
display: inline-block !important;
|
||||
height: auto !important;
|
||||
overflow: hidden !important;
|
||||
}
|
||||
.hd-1 {
|
||||
display: block !important;
|
||||
height: auto !important;
|
||||
overflow: visible !important;
|
||||
}
|
||||
.ht-1 {
|
||||
display: table !important;
|
||||
height: auto !important;
|
||||
overflow: visible !important;
|
||||
}
|
||||
.hr-1 {
|
||||
display: table-row !important;
|
||||
height: auto !important;
|
||||
overflow: visible !important;
|
||||
}
|
||||
.hc-1 {
|
||||
display: table-cell !important;
|
||||
height: auto !important;
|
||||
overflow: visible !important;
|
||||
}
|
||||
div.r.pr-16 > table > tbody > tr > td,
|
||||
div.r.pr-16 > div > table > tbody > tr > td {
|
||||
padding-right: 16px !important;
|
||||
}
|
||||
div.r.pl-16 > table > tbody > tr > td,
|
||||
div.r.pl-16 > div > table > tbody > tr > td {
|
||||
padding-left: 16px !important;
|
||||
}
|
||||
td.b.fw-1 > table {
|
||||
width: 100% !important;
|
||||
}
|
||||
td.fw-1 > table > tbody > tr > td > a {
|
||||
display: block !important;
|
||||
width: 100% !important;
|
||||
padding-left: 0 !important;
|
||||
padding-right: 0 !important;
|
||||
}
|
||||
td.b.fw-1 > table {
|
||||
width: 100% !important;
|
||||
}
|
||||
td.fw-1 > table > tbody > tr > td {
|
||||
width: 100% !important;
|
||||
padding-left: 0 !important;
|
||||
padding-right: 0 !important;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
<meta name="color-scheme" content="light dark" />
|
||||
<meta name="supported-color-schemes" content="light dark" />
|
||||
<!--[if gte mso 9]>
|
||||
<style>
|
||||
li {
|
||||
text-indent: -1em;
|
||||
}
|
||||
</style>
|
||||
<![endif]-->
|
||||
</head>
|
||||
<body
|
||||
lang="en"
|
||||
class="emailify"
|
||||
style="
|
||||
mso-line-height-rule: exactly;
|
||||
word-spacing: normal;
|
||||
background-color: #d6d6d6;
|
||||
"
|
||||
>
|
||||
<div class="bg" style="background-color: #d6d6d6">
|
||||
<!--[if mso | IE]>
|
||||
<table align="left" border="0" cellpadding="0" cellspacing="0" class="r-outlook -outlook pr-16-outlook pl-16-outlook -outlook" role="none" style="width:600px;" width="600" bgcolor="#f8f8f8"><tr><td style="line-height:0;font-size:0;mso-line-height-rule:exactly;">
|
||||
<![endif]-->
|
||||
<div
|
||||
class="r pr-16 pl-16"
|
||||
style="background-color: #f8f8f8; margin: 0px auto"
|
||||
>
|
||||
<table
|
||||
align="left"
|
||||
border="0"
|
||||
cellpadding="0"
|
||||
cellspacing="0"
|
||||
role="none"
|
||||
style="background-color: #f8f8f8; width: 100%"
|
||||
>
|
||||
<tbody>
|
||||
<tr>
|
||||
<td
|
||||
style="
|
||||
border: none;
|
||||
direction: ltr;
|
||||
font-size: 0;
|
||||
padding: 32px 32px 32px 32px;
|
||||
text-align: center;
|
||||
"
|
||||
>
|
||||
<div
|
||||
class="xc536 ogf c"
|
||||
style="
|
||||
font-size: 0;
|
||||
text-align: left;
|
||||
direction: ltr;
|
||||
display: inline-block;
|
||||
vertical-align: top;
|
||||
width: 100%;
|
||||
"
|
||||
>
|
||||
<table
|
||||
border="0"
|
||||
cellpadding="0"
|
||||
cellspacing="0"
|
||||
role="none"
|
||||
style="border-collapse: separate"
|
||||
width="600"
|
||||
>
|
||||
<tbody>
|
||||
<tr>
|
||||
<td
|
||||
style="
|
||||
background-color: #ffffff;
|
||||
border: 1px solid #f1f1f1;
|
||||
border-radius: 4px;
|
||||
vertical-align: top;
|
||||
padding: 40px 40px;
|
||||
"
|
||||
>
|
||||
<table
|
||||
border="0"
|
||||
cellpadding="0"
|
||||
cellspacing="0"
|
||||
role="none"
|
||||
width="100%"
|
||||
>
|
||||
<tbody>
|
||||
<tr>
|
||||
<td
|
||||
align="left"
|
||||
class="i m"
|
||||
style="
|
||||
font-size: 0;
|
||||
padding: 0;
|
||||
padding-bottom: 24px;
|
||||
word-break: break-word;
|
||||
border-bottom: 1px solid #cdd5df;
|
||||
"
|
||||
>
|
||||
<table
|
||||
border="0"
|
||||
cellpadding="0"
|
||||
cellspacing="0"
|
||||
role="none"
|
||||
style="
|
||||
border-collapse: collapse;
|
||||
border-spacing: 0;
|
||||
"
|
||||
>
|
||||
<tbody>
|
||||
<tr>
|
||||
<td>
|
||||
<img
|
||||
alt=""
|
||||
height="36"
|
||||
src="https://assets.appsmith.com/appsmith-logo-no-margin.png"
|
||||
style="
|
||||
border: 0;
|
||||
display: block;
|
||||
outline: none;
|
||||
text-decoration: none;
|
||||
height: 36px;
|
||||
width: auto;
|
||||
"
|
||||
title=""
|
||||
width="200"
|
||||
/>
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td
|
||||
align="left"
|
||||
class="x m"
|
||||
style="
|
||||
font-size: 0;
|
||||
padding-top: 24px;
|
||||
padding-bottom: 16px;
|
||||
word-break: break-word;
|
||||
"
|
||||
>
|
||||
<div style="text-align: left">
|
||||
<p style="margin: 0; text-align: left">
|
||||
<span
|
||||
style="
|
||||
font-size: 14px;
|
||||
font-family: SF Pro Text, Arial,
|
||||
sans-serif;
|
||||
color: #4c5664;
|
||||
line-height: 1.43;
|
||||
font-weight: 500;
|
||||
"
|
||||
>
|
||||
Hey,
|
||||
</span>
|
||||
</p>
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td
|
||||
align="left"
|
||||
class="x m"
|
||||
style="
|
||||
font-size: 0;
|
||||
padding-bottom: 16px;
|
||||
word-break: break-word;
|
||||
"
|
||||
>
|
||||
<div style="text-align: left">
|
||||
<p style="margin: 0; text-align: left">
|
||||
<span
|
||||
style="
|
||||
font-size: 14px;
|
||||
font-family: SF Pro Text, Arial,
|
||||
sans-serif;
|
||||
color: #4c5664;
|
||||
line-height: 1.43;
|
||||
"
|
||||
>{{inviterFirstName}} has invited you as
|
||||
<b>{{role}}</b> access to the Appsmith
|
||||
workspace
|
||||
<b>{{inviterWorkspaceName}}</b></span
|
||||
>
|
||||
</p>
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td
|
||||
align="left"
|
||||
class="x m"
|
||||
style="
|
||||
font-size: 0;
|
||||
padding-bottom: 24px;
|
||||
word-break: break-word;
|
||||
"
|
||||
>
|
||||
<div style="text-align: left">
|
||||
<p style="margin: 0; text-align: left">
|
||||
<span
|
||||
style="
|
||||
font-size: 14px;
|
||||
font-family: SF Pro Text, Arial,
|
||||
sans-serif;
|
||||
font-weight: 400;
|
||||
color: #4c5664;
|
||||
line-height: 1.43;
|
||||
"
|
||||
>Join your Appsmith workspace to get
|
||||
access to fast, usable, beautiful
|
||||
apps.</span
|
||||
>
|
||||
</p>
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td
|
||||
align="left"
|
||||
class="b fw-1"
|
||||
style="
|
||||
font-size: 0;
|
||||
padding: 0;
|
||||
padding-bottom: 24px;
|
||||
word-break: break-word;
|
||||
border-bottom: 1px solid #cdd5df;
|
||||
"
|
||||
>
|
||||
<table
|
||||
border="0"
|
||||
cellpadding="0"
|
||||
cellspacing="0"
|
||||
role="none"
|
||||
style="
|
||||
border-collapse: separate;
|
||||
line-height: 100%;
|
||||
"
|
||||
>
|
||||
<tbody>
|
||||
<tr>
|
||||
<td
|
||||
align="center"
|
||||
bgcolor="#f86a2b"
|
||||
role="none"
|
||||
style="
|
||||
border: none;
|
||||
border-radius: 4px 4px 4px 4px;
|
||||
cursor: auto;
|
||||
mso-padding-alt: 12px 0px 12px 0px;
|
||||
background: #f86a2b;
|
||||
color: #ffffff;
|
||||
"
|
||||
valign="middle"
|
||||
>
|
||||
<a
|
||||
href="{{primaryLinkUrl}}"
|
||||
style="
|
||||
display: inline-block;
|
||||
font-family: SF Pro Text, Arial,
|
||||
sans-serif;
|
||||
font-size: 14px;
|
||||
background: #f86a2b;
|
||||
color: #ffffff;
|
||||
font-weight: normal;
|
||||
line-height: 100%;
|
||||
margin: 0;
|
||||
text-decoration: none;
|
||||
text-transform: none;
|
||||
padding: 12px 12px 12px 12px;
|
||||
mso-padding-alt: 0;
|
||||
border-radius: 4px 4px 4px 4px;
|
||||
"
|
||||
target="_blank"
|
||||
>
|
||||
<span
|
||||
style="
|
||||
font-size: 14px;
|
||||
font-family: SF Pro Text, Arial,
|
||||
sans-serif;
|
||||
line-height: 1.43;
|
||||
color: #ffffff;
|
||||
"
|
||||
>Join your Appsmith
|
||||
workspace</span
|
||||
></a
|
||||
>
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td
|
||||
align="left"
|
||||
class="x m"
|
||||
style="
|
||||
font-size: 0;
|
||||
padding-top: 24px;
|
||||
word-break: break-word;
|
||||
"
|
||||
>
|
||||
<div style="text-align: left">
|
||||
<p style="margin: 0; text-align: left">
|
||||
<span
|
||||
style="
|
||||
font-size: 12px;
|
||||
font-family: SF Pro Text, Arial,
|
||||
sans-serif;
|
||||
font-weight: 400;
|
||||
color: #6a7585;
|
||||
line-height: 1.43;
|
||||
"
|
||||
>1390, Market Street, Suite 200, San
|
||||
Francisco, California 94102, United
|
||||
States</span
|
||||
>
|
||||
</p>
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
<!--[if mso | IE]>
|
||||
</td></tr></table>
|
||||
<![endif]-->
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
|
|
@ -1,286 +0,0 @@
|
|||
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
|
||||
<html data-editor-version="2" class="sg-campaigns" xmlns="http://www.w3.org/1999/xhtml">
|
||||
<head>
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1, minimum-scale=1, maximum-scale=1">
|
||||
<!--[if !mso]><!-->
|
||||
<meta http-equiv="X-UA-Compatible" content="IE=Edge">
|
||||
<!--<![endif]-->
|
||||
<!--[if (gte mso 9)|(IE)]>
|
||||
<xml>
|
||||
<o:OfficeDocumentSettings>
|
||||
<o:AllowPNG/>
|
||||
<o:PixelsPerInch>96</o:PixelsPerInch>
|
||||
</o:OfficeDocumentSettings>
|
||||
</xml>
|
||||
<![endif]-->
|
||||
<!--[if (gte mso 9)|(IE)]>
|
||||
<style type="text/css">
|
||||
body {
|
||||
width: 600px;
|
||||
margin: 0 auto;
|
||||
}
|
||||
|
||||
table {
|
||||
border-collapse: collapse;
|
||||
}
|
||||
|
||||
table, td {
|
||||
mso-table-lspace: 0pt;
|
||||
mso-table-rspace: 0pt;
|
||||
}
|
||||
|
||||
img {
|
||||
-ms-interpolation-mode: bicubic;
|
||||
}
|
||||
</style>
|
||||
<![endif]-->
|
||||
<style type="text/css">
|
||||
body, p, div {
|
||||
font-family: arial, helvetica, sans-serif;
|
||||
font-size: 14px;
|
||||
}
|
||||
|
||||
body {
|
||||
color: #000000;
|
||||
}
|
||||
|
||||
body a {
|
||||
color: #1188E6;
|
||||
text-decoration: none;
|
||||
}
|
||||
|
||||
p {
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
table.wrapper {
|
||||
width: 100% !important;
|
||||
table-layout: fixed;
|
||||
-webkit-font-smoothing: antialiased;
|
||||
-webkit-text-size-adjust: 100%;
|
||||
-moz-text-size-adjust: 100%;
|
||||
-ms-text-size-adjust: 100%;
|
||||
}
|
||||
|
||||
img.max-width {
|
||||
max-width: 100% !important;
|
||||
}
|
||||
|
||||
.column.of-2 {
|
||||
width: 50%;
|
||||
}
|
||||
|
||||
.column.of-3 {
|
||||
width: 33.333%;
|
||||
}
|
||||
|
||||
.column.of-4 {
|
||||
width: 25%;
|
||||
}
|
||||
|
||||
@media screen and (max-width: 480px) {
|
||||
.preheader .rightColumnContent,
|
||||
.footer .rightColumnContent {
|
||||
text-align: left !important;
|
||||
}
|
||||
|
||||
.preheader .rightColumnContent div,
|
||||
.preheader .rightColumnContent span,
|
||||
.footer .rightColumnContent div,
|
||||
.footer .rightColumnContent span {
|
||||
text-align: left !important;
|
||||
}
|
||||
|
||||
.preheader .rightColumnContent,
|
||||
.preheader .leftColumnContent {
|
||||
font-size: 80% !important;
|
||||
padding: 5px 0;
|
||||
}
|
||||
|
||||
table.wrapper-mobile {
|
||||
width: 100% !important;
|
||||
table-layout: fixed;
|
||||
}
|
||||
|
||||
img.max-width {
|
||||
height: auto !important;
|
||||
max-width: 100% !important;
|
||||
}
|
||||
|
||||
a.bulletproof-button {
|
||||
display: block !important;
|
||||
width: auto !important;
|
||||
font-size: 80%;
|
||||
padding-left: 0 !important;
|
||||
padding-right: 0 !important;
|
||||
}
|
||||
|
||||
.columns {
|
||||
width: 100% !important;
|
||||
}
|
||||
|
||||
.column {
|
||||
display: block !important;
|
||||
width: 100% !important;
|
||||
padding-left: 0 !important;
|
||||
padding-right: 0 !important;
|
||||
margin-left: 0 !important;
|
||||
margin-right: 0 !important;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
<!--user entered Head Start--><!--End Head user entered-->
|
||||
</head>
|
||||
<body>
|
||||
<center class="wrapper" data-link-color="#1188E6"
|
||||
data-body-style="font-size:14px; font-family:arial,helvetica,sans-serif; color:#000000; background-color:#FFFFFF;">
|
||||
<div class="webkit">
|
||||
<table cellpadding="0" cellspacing="0" border="0" width="100%" class="wrapper" bgcolor="#FFFFFF">
|
||||
<tbody>
|
||||
<tr>
|
||||
<td valign="top" bgcolor="#FFFFFF" width="100%">
|
||||
<table width="100%" role="content-container" class="outer" align="center" cellpadding="0"
|
||||
cellspacing="0" border="0">
|
||||
<tbody>
|
||||
<tr>
|
||||
<td width="100%">
|
||||
<table width="100%" cellpadding="0" cellspacing="0" border="0">
|
||||
<tbody>
|
||||
<tr>
|
||||
<td>
|
||||
<!--[if mso]>
|
||||
<center>
|
||||
<table>
|
||||
<tr>
|
||||
<td width="600">
|
||||
<![endif]-->
|
||||
<table width="100%" cellpadding="0" cellspacing="0" border="0"
|
||||
style="width:100%; max-width:600px;" align="center">
|
||||
<tbody>
|
||||
<tr>
|
||||
<td role="modules-container"
|
||||
style="padding:0px 0px 0px 0px; color:#000000; text-align:left;"
|
||||
bgcolor="#ffffff" width="100%" align="left">
|
||||
<table class="module preheader preheader-hide" role="module"
|
||||
data-type="preheader" border="0" cellpadding="0"
|
||||
cellspacing="0" width="100%"
|
||||
style="display: none !important; mso-hide: all; visibility: hidden; opacity: 0; color: transparent; height: 0; width: 0;">
|
||||
<tbody>
|
||||
<tr>
|
||||
<td role="module-content">
|
||||
<p></p>
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
<table class="wrapper" role="module" data-type="image"
|
||||
border="0" cellpadding="0" cellspacing="0" width="100%"
|
||||
style="table-layout: fixed;">
|
||||
<tbody>
|
||||
<tr>
|
||||
<td style="font-size:6px; line-height:10px; padding-top:36px;"
|
||||
valign="top" align="center">
|
||||
<div style="display:block;padding:02px;background-color:#FEB811">
|
||||
|
||||
</div>
|
||||
<div style="display:block;padding:10px;margin-bottom: 40px; color: #393939;background-color:#FFF8E2">
|
||||
<svg width="50" height="50" style="fill:#FEB811"clip-rule="evenodd" fill-rule="evenodd" color="yellow" stroke-linejoin="round" stroke-miterlimit="2" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg"><path d="m2.095 19.886 9.248-16.5c.133-.237.384-.384.657-.384.272 0 .524.147.656.384l9.248 16.5c.064.115.096.241.096.367 0 .385-.309.749-.752.749h-18.496c-.44 0-.752-.36-.752-.749 0-.126.031-.252.095-.367zm9.907-6.881c-.414 0-.75.336-.75.75v3.5c0 .414.336.75.75.75s.75-.336.75-.75v-3.5c0-.414-.336-.75-.75-.75zm-.002-3c-.552 0-1 .448-1 1s.448 1 1 1 1-.448 1-1-.448-1-1-1z" fill-rule="nonzero"/></svg>
|
||||
<div style="margin:8px 16px 16px 16px;font-size:18px;line-height: 35px;">
|
||||
<i class="fa-solid fa-triangle-exclamation"></i>
|
||||
<b>Commenting is deprecated</b><br>
|
||||
We will be removing comments from Appsmith in v1.7.12<br>
|
||||
<a href="https://appsmith.notion.site/Deprecating-real-time-commenting-60a307d2c5e1485b85ff95afebb616eb" target ="_blank" style="text-decoration: underline;font-size:16px;color:#393939;">Learn More</a>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td style="font-size:6px; line-height:10px; padding-top:px;"
|
||||
valign="top" align="center">
|
||||
<a href="https://www.appsmith.com/">
|
||||
<img width="50px" src="https://assets.appsmith.com/email/appsmith_logo_20x20.png" />
|
||||
</a>
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
<table class="module" role="module" data-type="text" border="0"
|
||||
cellpadding="0" cellspacing="0" width="100%"
|
||||
style="table-layout: fixed;">
|
||||
<tbody>
|
||||
<tr>
|
||||
<td style="padding:0px 0px 18px 0px; line-height:22px; text-align:center; background-color:#ffffff;"
|
||||
height="100%" valign="top" bgcolor="#ffffff"
|
||||
role="module-content">
|
||||
<div style="margin-top:37px;font-size:18px;line-height: 35px;">
|
||||
<b>{{Commenter_Name}}</b>,
|
||||
{{#NewComment}} added {{/NewComment}}
|
||||
{{#Resolved}} resolved {{/Resolved}}
|
||||
{{#Replied}} replied to {{/Replied}}
|
||||
{{#Mentioned}} mentioned you in {{/Mentioned}}
|
||||
{{#Resolved}} a comment thread {{/Resolved}}
|
||||
{{^Resolved}} a comment on {{/Resolved}}
|
||||
<br><b>{{Application_Name}}, {{Page_Name}}</b>:
|
||||
</div>
|
||||
{{#Comment_Body}}
|
||||
<div style="display:block;padding:10px;margin-top: 40px; color: #5c5959;background-color:#F0F0F0">
|
||||
{{ . }}
|
||||
</div>
|
||||
{{/Comment_Body}}
|
||||
<div style="margin-top:40px">
|
||||
<a href="{{commentUrl}}"
|
||||
style="background-color:#ff6d2d; border:1px solid #ff6d2d; border-color:#ff6d2d; border-width:1px; color:#ffffff; display:inline-block; font-weight:400; letter-spacing:0px; line-height:6px; padding:12px 18px 12px 18px; text-align:center; text-decoration:none; border-style:solid; font-family:tahoma,geneva,sans-serif; font-size:16px;"
|
||||
target="_blank">VIEW THE COMMENT</a>
|
||||
</div>
|
||||
<!-- <div style="margin-top:23px">You can answer by replying to this email.</div>-->
|
||||
<hr style="margin-top:40px;margin-bottom:40px;height:0px;border:0; border-top: 1px solid #E0DEDE;" />
|
||||
<div><a href="{{UnsubscribeLink}}" style="text-decoration:underline">Turn off comment notifications for this thread</a></div>
|
||||
<div style="font-size:12px;line-height:19px;color:#A9A7A7;margin-top:17px">
|
||||
Appsmith is an open source framework to build admin panels, CRUD apps and workflows. Build everything you need, 10x faster.
|
||||
</div>
|
||||
<div style="margin-top:32px">
|
||||
<a href="https://www.youtube.com/appsmith" style="text-decoration:none">
|
||||
<img width="20px" src="https://assets.appsmith.com/email/ic_youtube.png" /></a>
|
||||
<a href="https://twitter.com/theappsmith" style="margin-left:25px;margin-right:25px;text-decoration:none">
|
||||
<img width="20px" src="https://assets.appsmith.com/email/ic_twitter.png" /></a>
|
||||
<a href="https://www.linkedin.com/company/appsmith" style="text-decoration:none">
|
||||
<img width="20px" src="https://assets.appsmith.com/email/ic_linkedin.png" /></a>
|
||||
</div>
|
||||
<div style="font-size:12px;line-height:19px;color:#A9A7A7;margin-top:42px">
|
||||
2261 Market Street #4147, United States, San Francisco, California, 94114, US
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
<!--[if mso]>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
</center>
|
||||
<![endif]-->
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</center>
|
||||
|
||||
|
||||
</body>
|
||||
</html>
|
||||
File diff suppressed because it is too large
Load Diff
|
|
@ -1,123 +0,0 @@
|
|||
<!doctype html>
|
||||
<html lang="en" xmlns="http://www.w3.org/1999/xhtml">
|
||||
<head>
|
||||
<title> Reset password for your Appsmith account </title>
|
||||
<!--[if !mso]><!-->
|
||||
<meta http-equiv="X-UA-Compatible" content="IE=edge">
|
||||
<!--<![endif]-->
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||
<style type="text/css">
|
||||
#outlook a{padding:0;}body{margin:0;padding:0;-webkit-text-size-adjust:100%;-ms-text-size-adjust:100%;}table,td{border-collapse:collapse;mso-table-lspace:0pt;mso-table-rspace:0pt;}img{border:0;height:auto;line-height:100%;outline:none;text-decoration:none;-ms-interpolation-mode:bicubic;}p{display:block;margin:0;}
|
||||
</style>
|
||||
<!--[if mso]> <noscript><xml><o:OfficeDocumentSettings><o:AllowPNG/><o:PixelsPerInch>96</o:PixelsPerInch></o:OfficeDocumentSettings></xml></noscript>
|
||||
<![endif]-->
|
||||
<!--[if lte mso 11]>
|
||||
<style type="text/css">
|
||||
.ogf{width:100% !important;}
|
||||
</style>
|
||||
<![endif]-->
|
||||
<!--[if !mso]><!-->
|
||||
<link href="https://fonts.googleapis.com/css?family=Inter:700" rel="stylesheet" type="text/css">
|
||||
<style type="text/css">
|
||||
|
||||
</style>
|
||||
<!--<![endif]-->
|
||||
<style type="text/css">
|
||||
@media only screen and (min-width:599px){.xc536{width:536px!important;max-width:536px;}.xc0{width:0px!important;max-width:0;}.xc16{width:16px!important;max-width:16px;}}
|
||||
</style>
|
||||
<style media="screen and (min-width:599px)">.moz-text-html .xc536{width:536px!important;max-width:536px;}.moz-text-html .xc0{width:0px!important;max-width:0;}.moz-text-html .xc16{width:16px!important;max-width:16px;}
|
||||
</style>
|
||||
<style type="text/css">
|
||||
@media only screen and (max-width:599px){table.fwm{width:100%!important;}td.fwm{width:auto!important;}}
|
||||
</style>
|
||||
<style type="text/css">
|
||||
u+.emailify a,#MessageViewBody a,a[x-apple-data-detectors]{color:inherit!important;text-decoration:none!important;font-size:inherit!important;font-family:inherit!important;font-weight:inherit!important;line-height:inherit!important;}span.MsoHyperlink{mso-style-priority:99;color:inherit;}span.MsoHyperlinkFollowed{mso-style-priority:99;color:inherit;}td.b .klaviyo-image-block{display:inline;vertical-align:middle;}
|
||||
@media only screen and (max-width:599px){.emailify{height:100%!important;margin:0!important;padding:0!important;width:100%!important;}u+.emailify .glist{margin-left:1em!important;}td.x{padding-left:0!important;padding-right:0!important;}.fwm img{max-width:100%!important;height:auto!important;}td.b.nw>table,td.b.nw a{width:auto!important;}td.stk{border:0!important;}br.sb{display:none!important;}.thd-1 .i-thumbnail{display:inline-block!important;height:auto!important;overflow:hidden!important;}.hd-1{display:block!important;height:auto!important;overflow:visible!important;}.ht-1{display:table!important;height:auto!important;overflow:visible!important;}.hr-1{display:table-row!important;height:auto!important;overflow:visible!important;}.hc-1{display:table-cell!important;height:auto!important;overflow:visible!important;}div.r.pr-16>table>tbody>tr>td,div.r.pr-16>div>table>tbody>tr>td{padding-right:16px!important}div.r.pl-16>table>tbody>tr>td,div.r.pl-16>div>table>tbody>tr>td{padding-left:16px!important}td.b.fw-1>table{width:100%!important}td.fw-1>table>tbody>tr>td>a{display:block!important;width:100%!important;padding-left:0!important;padding-right:0!important;}td.b.fw-1>table{width:100%!important}td.fw-1>table>tbody>tr>td{width:100%!important;padding-left:0!important;padding-right:0!important;}}
|
||||
</style>
|
||||
<meta name="color-scheme" content="light dark">
|
||||
<meta name="supported-color-schemes" content="light dark">
|
||||
<!--[if gte mso 9]>
|
||||
<style>li{text-indent:-1em;}
|
||||
</style>
|
||||
<![endif]-->
|
||||
</head>
|
||||
<body lang="en" class="emailify" style="mso-line-height-rule:exactly;word-spacing:normal;background-color:#d6d6d6;"><div class="bg" style="background-color:#d6d6d6;">
|
||||
<!--[if mso | IE]>
|
||||
<table align="center" border="0" cellpadding="0" cellspacing="0" class="r-outlook -outlook pr-16-outlook pl-16-outlook -outlook" role="none" style="width:600px;" width="600" bgcolor="#f8f8f8"><tr><td style="line-height:0;font-size:0;mso-line-height-rule:exactly;">
|
||||
<![endif]--><div class="r pr-16 pl-16" style="background:#f8f8f8;background-color:#f8f8f8;margin:0px auto;max-width:600px;">
|
||||
<table align="center" border="0" cellpadding="0" cellspacing="0" role="none" style="background:#f8f8f8;background-color:#f8f8f8;width:100%;"><tbody><tr><td style="border:none;direction:ltr;font-size:0;padding:32px 32px 8px 32px;text-align:left;">
|
||||
<!--[if mso | IE]>
|
||||
<table role="none" border="0" cellpadding="0" cellspacing="0"><tr><td class="m-outlook c-outlook -outlook -outlook" style="vertical-align:top;width:536px;">
|
||||
<![endif]--><div class="xc536 ogf m c" style="font-size:0;text-align:left;direction:ltr;display:inline-block;vertical-align:top;width:100%;">
|
||||
<table border="0" cellpadding="0" cellspacing="0" role="none" style="border:none;vertical-align:top;" width="100%"><tbody><tr><td align="center" class="d" style="font-size:0;padding:0;word-break:break-word;"><h1 style="border-top:solid 8px #f86a2b;font-size:1px;margin:0px auto;width:100%;"></h1>
|
||||
<!--[if mso | IE]>
|
||||
<table align="center" border="0" cellpadding="0" cellspacing="0" style="border-top:solid 8px #f86a2b;font-size:1px;margin:0px auto;width:536px;" role="none" width="536px"><tr><td style="height:0;line-height:0;">
|
||||
</td></tr></table>
|
||||
<![endif]-->
|
||||
</td></tr></tbody></table></div>
|
||||
<!--[if mso | IE]>
|
||||
</td><td class="g-outlook" style="vertical-align:top;width:0;">
|
||||
<![endif]--><div class="xc0 ogf g" style="font-size:0;text-align:left;direction:ltr;display:inline-block;vertical-align:top;width:100%;">
|
||||
<table border="0" cellpadding="0" cellspacing="0" role="none" width="100%"><tbody><tr><td style="vertical-align:top;padding:0;">
|
||||
<table border="0" cellpadding="0" cellspacing="0" role="none" width="100%"><tbody></tbody></table>
|
||||
</td></tr></tbody></table></div>
|
||||
<!--[if mso | IE]>
|
||||
</td><td class="c-outlook -outlook -outlook" style="vertical-align:top;width:536px;">
|
||||
<![endif]--><div class="xc536 ogf c" style="font-size:0;text-align:left;direction:ltr;display:inline-block;vertical-align:top;width:100%;">
|
||||
<table border="0" cellpadding="0" cellspacing="0" role="none" width="100%"><tbody><tr><td style="background-color:#fffffe;border:none;vertical-align:top;padding:40px 24px 24px 24px;">
|
||||
<table border="0" cellpadding="0" cellspacing="0" role="none" width="100%"><tbody><tr><td align="center" class="i m" style="font-size:0;padding:0;padding-bottom:16px;word-break:break-word;">
|
||||
<table border="0" cellpadding="0" cellspacing="0" role="none" style="border-collapse:collapse;border-spacing:0;"><tbody><tr><td style="width:200px;"> <img alt="" height="auto" src="https://assets.appsmith.com/appsmith-logo-no-margin.png" style="border:0;display:block;outline:none;text-decoration:none;height:auto;width:100%;font-size:13px;" title="" width="200">
|
||||
</td></tr></tbody></table>
|
||||
</td></tr><tr><td class="s m" style="font-size:0;padding:0;padding-bottom:16px;word-break:break-word;"><div style="height:1px;line-height:1px;"> </div>
|
||||
</td></tr><tr><td align="center" class="x m" style="font-size:0;padding-bottom:16px;word-break:break-word;"><div style="text-align:center;"><p style="Margin:0;text-align:center;"><span style="font-size:20px;font-family:SF Pro Text,Arial,sans-serif;font-weight:600;color:#000000;line-height:24px;">Password reset link for Appsmith apps</span></p></div>
|
||||
</td></tr><tr><td align="center" class="x m" style="font-size:0;padding-bottom:16px;word-break:break-word;"><div style="text-align:center;"><p style="Margin:0;text-align:center;"><span style="font-size:16px;font-family:SF Pro Text,Arial,sans-serif;font-weight:400;color:#000000;line-height:24px;">Forgotten your password? No worries, we’ve got you covered. This link will expire in 48 hours.</span></p></div>
|
||||
</td></tr><tr><td class="s m" style="font-size:0;padding:0;padding-bottom:16px;word-break:break-word;"><div style="height:4px;line-height:4px;"> </div>
|
||||
</td></tr><tr><td align="center" class="b fw-1" style="font-size:0;padding:0;padding-bottom:0;word-break:break-word;">
|
||||
<table border="0" cellpadding="0" cellspacing="0" role="none" style="border-collapse:separate;width:154px;line-height:100%;"><tbody><tr><td align="center" bgcolor="#f86a2b" role="none" style="border:none;border-radius:4px 4px 4px 4px;cursor:auto;mso-padding-alt:12px 0px 12px 0px;background:#f86a2b;" valign="middle"> <a href="{{resetUrl}}" style="display:inline-block;width:154px;background:#f86a2b;color:#ffffff;font-family:Inter,Arial,sans-serif;font-size:13px;font-weight:normal;line-height:100%;margin:0;text-decoration:none;text-transform:none;padding:12px 0px 12px 0px;mso-padding-alt:0;border-radius:4px 4px 4px 4px;" target="_blank"> <span style="font-size:14px;font-family:Inter,Arial,sans-serif;font-weight:700;color:#ffffff;line-height:17px;">Reset Password</span></a>
|
||||
</td></tr></tbody></table>
|
||||
</td></tr></tbody></table>
|
||||
</td></tr></tbody></table></div>
|
||||
<!--[if mso | IE]>
|
||||
</td></tr></table>
|
||||
<![endif]-->
|
||||
</td></tr></tbody></table></div>
|
||||
<!--[if mso | IE]>
|
||||
</td></tr></table>
|
||||
<table align="center" border="0" cellpadding="0" cellspacing="0" class="r-outlook -outlook pr-16-outlook pl-16-outlook -outlook" role="none" style="width:600px;" width="600" bgcolor="#f8f8f8"><tr><td style="line-height:0;font-size:0;mso-line-height-rule:exactly;">
|
||||
<![endif]--><div class="r pr-16 pl-16" style="background:#f8f8f8;background-color:#f8f8f8;margin:0px auto;max-width:600px;">
|
||||
<table align="center" border="0" cellpadding="0" cellspacing="0" role="none" style="background:#f8f8f8;background-color:#f8f8f8;width:100%;"><tbody><tr><td style="border:none;direction:ltr;font-size:0;padding:16px 32px 16px 32px;text-align:left;">
|
||||
<!--[if mso | IE]>
|
||||
<table role="none" border="0" cellpadding="0" cellspacing="0"><tr><td class="m-outlook c-outlook -outlook -outlook" style="vertical-align:top;width:536px;">
|
||||
<![endif]--><div class="xc536 ogf m c" style="font-size:0;text-align:left;direction:ltr;display:inline-block;vertical-align:top;width:100%;">
|
||||
<table border="0" cellpadding="0" cellspacing="0" role="none" style="border:none;vertical-align:top;" width="100%"><tbody><tr><td align="center" class="d" style="font-size:0;padding:0;word-break:break-word;"><p style="border-top:solid 1px #cccccc;font-size:1px;margin:0px auto;width:100%;"></p>
|
||||
<!--[if mso | IE]>
|
||||
<table align="center" border="0" cellpadding="0" cellspacing="0" style="border-top:solid 1px #cccccc;font-size:1px;margin:0px auto;width:536px;" role="none" width="536px"><tr><td style="height:0;line-height:0;">
|
||||
</td></tr></table>
|
||||
<![endif]-->
|
||||
</td></tr></tbody></table></div>
|
||||
<!--[if mso | IE]>
|
||||
</td><td class="g-outlook" style="vertical-align:top;width:16px;">
|
||||
<![endif]--><div class="xc16 ogf g" style="font-size:0;text-align:left;direction:ltr;display:inline-block;vertical-align:top;width:100%;">
|
||||
<table border="0" cellpadding="0" cellspacing="0" role="none" width="100%"><tbody><tr><td style="vertical-align:top;padding:0;">
|
||||
<table border="0" cellpadding="0" cellspacing="0" role="none" width="100%"><tbody></tbody></table>
|
||||
</td></tr></tbody></table></div>
|
||||
<!--[if mso | IE]>
|
||||
</td><td class="c-outlook -outlook -outlook" style="vertical-align:top;width:536px;">
|
||||
<![endif]--><div class="xc536 ogf c" style="font-size:0;text-align:left;direction:ltr;display:inline-block;vertical-align:top;width:100%;">
|
||||
<table border="0" cellpadding="0" cellspacing="0" role="none" width="100%"><tbody><tr><td style="border:none;vertical-align:top;padding:0px 12px 0px 12px;">
|
||||
<table border="0" cellpadding="0" cellspacing="0" role="none" width="100%"><tbody><tr><td align="left" class="i fw-1 m" style="font-size:0;padding:0;padding-bottom:8px;word-break:break-word;">
|
||||
<table border="0" cellpadding="0" cellspacing="0" role="none" style="border-collapse:collapse;border-spacing:0;" class="fwm"><tbody><tr><td style="width:512px;" class="fwm"> <img alt="" height="auto" src="https://emailify.b-cdn.net/f76e7fcbed28d8e5b3acc27c5109a06e.png" style="border:0;display:block;outline:none;text-decoration:none;height:auto;width:100%;font-size:13px;" title="" width="512">
|
||||
</td></tr></tbody></table>
|
||||
</td></tr><tr><td align="center" class="x" style="font-size:0;padding-bottom:0;word-break:break-word;"><div style="text-align:center;"><p style="Margin:0;text-align:center;"><span style="font-size:14px;font-family:SF Pro Text,Arial,sans-serif;font-weight:400;color:#b3b3b3;line-height:22px;">Appsmith is an open source framework that helps developer and companies to build powerful internal tools.</span></p></div>
|
||||
</td></tr></tbody></table>
|
||||
</td></tr></tbody></table></div>
|
||||
<!--[if mso | IE]>
|
||||
</td></tr></table>
|
||||
<![endif]-->
|
||||
</td></tr></tbody></table></div>
|
||||
<!--[if mso | IE]>
|
||||
</td></tr></table>
|
||||
<![endif]--></div>
|
||||
</body>
|
||||
</html>
|
||||
|
|
@ -1,123 +0,0 @@
|
|||
<!doctype html>
|
||||
<html lang="en" xmlns="http://www.w3.org/1999/xhtml">
|
||||
<head>
|
||||
<title>{{inviterFirstName}} has invited you to collaborate</title>
|
||||
<!--[if !mso]><!-->
|
||||
<meta http-equiv="X-UA-Compatible" content="IE=edge">
|
||||
<!--<![endif]-->
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||
<style type="text/css">
|
||||
#outlook a{padding:0;}body{margin:0;padding:0;-webkit-text-size-adjust:100%;-ms-text-size-adjust:100%;}table,td{border-collapse:collapse;mso-table-lspace:0pt;mso-table-rspace:0pt;}img{border:0;height:auto;line-height:100%;outline:none;text-decoration:none;-ms-interpolation-mode:bicubic;}p{display:block;margin:0;}
|
||||
</style>
|
||||
<!--[if mso]> <noscript><xml><o:OfficeDocumentSettings><o:AllowPNG/><o:PixelsPerInch>96</o:PixelsPerInch></o:OfficeDocumentSettings></xml></noscript>
|
||||
<![endif]-->
|
||||
<!--[if lte mso 11]>
|
||||
<style type="text/css">
|
||||
.ogf{width:100% !important;}
|
||||
</style>
|
||||
<![endif]-->
|
||||
<!--[if !mso]><!-->
|
||||
<link href="https://fonts.googleapis.com/css?family=Inter:700" rel="stylesheet" type="text/css">
|
||||
<style type="text/css">
|
||||
|
||||
</style>
|
||||
<!--<![endif]-->
|
||||
<style type="text/css">
|
||||
@media only screen and (min-width:599px){.xc536{width:536px!important;max-width:536px;}.xc0{width:0px!important;max-width:0;}.xc16{width:16px!important;max-width:16px;}}
|
||||
</style>
|
||||
<style media="screen and (min-width:599px)">.moz-text-html .xc536{width:536px!important;max-width:536px;}.moz-text-html .xc0{width:0px!important;max-width:0;}.moz-text-html .xc16{width:16px!important;max-width:16px;}
|
||||
</style>
|
||||
<style type="text/css">
|
||||
@media only screen and (max-width:599px){table.fwm{width:100%!important;}td.fwm{width:auto!important;}}
|
||||
</style>
|
||||
<style type="text/css">
|
||||
u+.emailify a,#MessageViewBody a,a[x-apple-data-detectors]{color:inherit!important;text-decoration:none!important;font-size:inherit!important;font-family:inherit!important;font-weight:inherit!important;line-height:inherit!important;}span.MsoHyperlink{mso-style-priority:99;color:inherit;}span.MsoHyperlinkFollowed{mso-style-priority:99;color:inherit;}td.b .klaviyo-image-block{display:inline;vertical-align:middle;}
|
||||
@media only screen and (max-width:599px){.emailify{height:100%!important;margin:0!important;padding:0!important;width:100%!important;}u+.emailify .glist{margin-left:1em!important;}td.x{padding-left:0!important;padding-right:0!important;}.fwm img{max-width:100%!important;height:auto!important;}td.b.nw>table,td.b.nw a{width:auto!important;}td.stk{border:0!important;}br.sb{display:none!important;}.thd-1 .i-thumbnail{display:inline-block!important;height:auto!important;overflow:hidden!important;}.hd-1{display:block!important;height:auto!important;overflow:visible!important;}.ht-1{display:table!important;height:auto!important;overflow:visible!important;}.hr-1{display:table-row!important;height:auto!important;overflow:visible!important;}.hc-1{display:table-cell!important;height:auto!important;overflow:visible!important;}div.r.pr-16>table>tbody>tr>td,div.r.pr-16>div>table>tbody>tr>td{padding-right:16px!important}div.r.pl-16>table>tbody>tr>td,div.r.pl-16>div>table>tbody>tr>td{padding-left:16px!important}td.b.fw-1>table{width:100%!important}td.fw-1>table>tbody>tr>td>a{display:block!important;width:100%!important;padding-left:0!important;padding-right:0!important;}td.b.fw-1>table{width:100%!important}td.fw-1>table>tbody>tr>td{width:100%!important;padding-left:0!important;padding-right:0!important;}}
|
||||
</style>
|
||||
<meta name="color-scheme" content="light dark">
|
||||
<meta name="supported-color-schemes" content="light dark">
|
||||
<!--[if gte mso 9]>
|
||||
<style>li{text-indent:-1em;}
|
||||
</style>
|
||||
<![endif]-->
|
||||
</head>
|
||||
<body lang="en" class="emailify" style="mso-line-height-rule:exactly;word-spacing:normal;background-color:#d6d6d6;"><div class="bg" style="background-color:#d6d6d6;">
|
||||
<!--[if mso | IE]>
|
||||
<table align="center" border="0" cellpadding="0" cellspacing="0" class="r-outlook -outlook pr-16-outlook pl-16-outlook -outlook" role="none" style="width:600px;" width="600" bgcolor="#f8f8f8"><tr><td style="line-height:0;font-size:0;mso-line-height-rule:exactly;">
|
||||
<![endif]--><div class="r pr-16 pl-16" style="background:#f8f8f8;background-color:#f8f8f8;margin:0px auto;max-width:600px;">
|
||||
<table align="center" border="0" cellpadding="0" cellspacing="0" role="none" style="background:#f8f8f8;background-color:#f8f8f8;width:100%;"><tbody><tr><td style="border:none;direction:ltr;font-size:0;padding:32px 32px 8px 32px;text-align:left;">
|
||||
<!--[if mso | IE]>
|
||||
<table role="none" border="0" cellpadding="0" cellspacing="0"><tr><td class="m-outlook c-outlook -outlook -outlook" style="vertical-align:top;width:536px;">
|
||||
<![endif]--><div class="xc536 ogf m c" style="font-size:0;text-align:left;direction:ltr;display:inline-block;vertical-align:top;width:100%;">
|
||||
<table border="0" cellpadding="0" cellspacing="0" role="none" style="border:none;vertical-align:top;" width="100%"><tbody><tr><td align="center" class="d" style="font-size:0;padding:0;word-break:break-word;"><h1 style="border-top:solid 8px #f86a2b;font-size:1px;margin:0px auto;width:100%;"></h1>
|
||||
<!--[if mso | IE]>
|
||||
<table align="center" border="0" cellpadding="0" cellspacing="0" style="border-top:solid 8px #f86a2b;font-size:1px;margin:0px auto;width:536px;" role="none" width="536px"><tr><td style="height:0;line-height:0;">
|
||||
</td></tr></table>
|
||||
<![endif]-->
|
||||
</td></tr></tbody></table></div>
|
||||
<!--[if mso | IE]>
|
||||
</td><td class="g-outlook" style="vertical-align:top;width:0;">
|
||||
<![endif]--><div class="xc0 ogf g" style="font-size:0;text-align:left;direction:ltr;display:inline-block;vertical-align:top;width:100%;">
|
||||
<table border="0" cellpadding="0" cellspacing="0" role="none" width="100%"><tbody><tr><td style="vertical-align:top;padding:0;">
|
||||
<table border="0" cellpadding="0" cellspacing="0" role="none" width="100%"><tbody></tbody></table>
|
||||
</td></tr></tbody></table></div>
|
||||
<!--[if mso | IE]>
|
||||
</td><td class="c-outlook -outlook -outlook" style="vertical-align:top;width:536px;">
|
||||
<![endif]--><div class="xc536 ogf c" style="font-size:0;text-align:left;direction:ltr;display:inline-block;vertical-align:top;width:100%;">
|
||||
<table border="0" cellpadding="0" cellspacing="0" role="none" width="100%"><tbody><tr><td style="background-color:#fffffe;border:none;vertical-align:top;padding:40px 24px 24px 24px;">
|
||||
<table border="0" cellpadding="0" cellspacing="0" role="none" width="100%"><tbody><tr><td align="center" class="i m" style="font-size:0;padding:0;padding-bottom:16px;word-break:break-word;">
|
||||
<table border="0" cellpadding="0" cellspacing="0" role="none" style="border-collapse:collapse;border-spacing:0;"><tbody><tr><td style="width:200px;"> <img alt="" height="auto" src="https://assets.appsmith.com/appsmith-logo-no-margin.png" style="border:0;display:block;outline:none;text-decoration:none;height:auto;width:100%;font-size:13px;" title="" width="200">
|
||||
</td></tr></tbody></table>
|
||||
</td></tr><tr><td class="s m" style="font-size:0;padding:0;padding-bottom:16px;word-break:break-word;"><div style="height:1px;line-height:1px;"> </div>
|
||||
</td></tr><tr><td align="center" class="x m" style="font-size:0;padding-bottom:16px;word-break:break-word;"><div style="text-align:center;"><p style="Margin:0;text-align:center;"><span style="font-size:20px;font-family:SF Pro Text,Arial,sans-serif;font-weight:600;color:#000000;line-height:24px;">{{inviterFirstName}} has invited you to collaborate on the workspace "{{inviterWorkspaceName}}"</span></p></div>
|
||||
</td></tr><tr><td align="center" class="x m" style="font-size:0;padding-bottom:16px;word-break:break-word;"><div style="text-align:center;"><p style="Margin:0;text-align:center;"><span style="font-size:16px;font-family:SF Pro Text,Arial,sans-serif;font-weight:400;color:#000000;line-height:24px;">You have been invited to join the workspace "{{inviterWorkspaceName}}" in Appsmith. Accept the invite to create your account and get started.</span></p></div>
|
||||
</td></tr><tr><td class="s m" style="font-size:0;padding:0;padding-bottom:16px;word-break:break-word;"><div style="height:4px;line-height:4px;"> </div>
|
||||
</td></tr><tr><td align="center" class="b fw-1" style="font-size:0;padding:0;padding-bottom:0;word-break:break-word;">
|
||||
<table border="0" cellpadding="0" cellspacing="0" role="none" style="border-collapse:separate;width:135px;line-height:100%;"><tbody><tr><td align="center" bgcolor="#f86a2b" role="none" style="border:none;border-radius:4px 4px 4px 4px;cursor:auto;mso-padding-alt:12px 0px 12px 0px;background:#f86a2b;" valign="middle"> <a href="{{primaryLinkUrl}}" style="display:inline-block;width:135px;background:#f86a2b;color:#ffffff;font-family:Inter,Arial,sans-serif;font-size:13px;font-weight:normal;line-height:100%;margin:0;text-decoration:none;text-transform:none;padding:12px 0px 12px 0px;mso-padding-alt:0;border-radius:4px 4px 4px 4px;" target="_blank"> <span style="font-size:14px;font-family:Inter,Arial,sans-serif;font-weight:700;color:#ffffff;line-height:17px;">{{primaryLinkText}}</span></a>
|
||||
</td></tr></tbody></table>
|
||||
</td></tr></tbody></table>
|
||||
</td></tr></tbody></table></div>
|
||||
<!--[if mso | IE]>
|
||||
</td></tr></table>
|
||||
<![endif]-->
|
||||
</td></tr></tbody></table></div>
|
||||
<!--[if mso | IE]>
|
||||
</td></tr></table>
|
||||
<table align="center" border="0" cellpadding="0" cellspacing="0" class="r-outlook -outlook pr-16-outlook pl-16-outlook -outlook" role="none" style="width:600px;" width="600" bgcolor="#f8f8f8"><tr><td style="line-height:0;font-size:0;mso-line-height-rule:exactly;">
|
||||
<![endif]--><div class="r pr-16 pl-16" style="background:#f8f8f8;background-color:#f8f8f8;margin:0px auto;max-width:600px;">
|
||||
<table align="center" border="0" cellpadding="0" cellspacing="0" role="none" style="background:#f8f8f8;background-color:#f8f8f8;width:100%;"><tbody><tr><td style="border:none;direction:ltr;font-size:0;padding:16px 32px 16px 32px;text-align:left;">
|
||||
<!--[if mso | IE]>
|
||||
<table role="none" border="0" cellpadding="0" cellspacing="0"><tr><td class="m-outlook c-outlook -outlook -outlook" style="vertical-align:top;width:536px;">
|
||||
<![endif]--><div class="xc536 ogf m c" style="font-size:0;text-align:left;direction:ltr;display:inline-block;vertical-align:top;width:100%;">
|
||||
<table border="0" cellpadding="0" cellspacing="0" role="none" style="border:none;vertical-align:top;" width="100%"><tbody><tr><td align="center" class="d" style="font-size:0;padding:0;word-break:break-word;"><p style="border-top:solid 1px #cccccc;font-size:1px;margin:0px auto;width:100%;"></p>
|
||||
<!--[if mso | IE]>
|
||||
<table align="center" border="0" cellpadding="0" cellspacing="0" style="border-top:solid 1px #cccccc;font-size:1px;margin:0px auto;width:536px;" role="none" width="536px"><tr><td style="height:0;line-height:0;">
|
||||
</td></tr></table>
|
||||
<![endif]-->
|
||||
</td></tr></tbody></table></div>
|
||||
<!--[if mso | IE]>
|
||||
</td><td class="g-outlook" style="vertical-align:top;width:16px;">
|
||||
<![endif]--><div class="xc16 ogf g" style="font-size:0;text-align:left;direction:ltr;display:inline-block;vertical-align:top;width:100%;">
|
||||
<table border="0" cellpadding="0" cellspacing="0" role="none" width="100%"><tbody><tr><td style="vertical-align:top;padding:0;">
|
||||
<table border="0" cellpadding="0" cellspacing="0" role="none" width="100%"><tbody></tbody></table>
|
||||
</td></tr></tbody></table></div>
|
||||
<!--[if mso | IE]>
|
||||
</td><td class="c-outlook -outlook -outlook" style="vertical-align:top;width:536px;">
|
||||
<![endif]--><div class="xc536 ogf c" style="font-size:0;text-align:left;direction:ltr;display:inline-block;vertical-align:top;width:100%;">
|
||||
<table border="0" cellpadding="0" cellspacing="0" role="none" width="100%"><tbody><tr><td style="border:none;vertical-align:top;padding:0px 12px 0px 12px;">
|
||||
<table border="0" cellpadding="0" cellspacing="0" role="none" width="100%"><tbody><tr><td align="left" class="i fw-1 m" style="font-size:0;padding:0;padding-bottom:8px;word-break:break-word;">
|
||||
<table border="0" cellpadding="0" cellspacing="0" role="none" style="border-collapse:collapse;border-spacing:0;" class="fwm"><tbody><tr><td style="width:512px;" class="fwm"> <img alt="" height="auto" src="https://emailify.b-cdn.net/f76e7fcbed28d8e5b3acc27c5109a06e.png" style="border:0;display:block;outline:none;text-decoration:none;height:auto;width:100%;font-size:13px;" title="" width="512">
|
||||
</td></tr></tbody></table>
|
||||
</td></tr><tr><td align="center" class="x" style="font-size:0;padding-bottom:0;word-break:break-word;"><div style="text-align:center;"><p style="Margin:0;text-align:center;"><span style="font-size:14px;font-family:SF Pro Text,Arial,sans-serif;font-weight:400;color:#b3b3b3;line-height:22px;">Appsmith is an open source framework that helps developer and companies to build powerful internal tools.</span></p></div>
|
||||
</td></tr></tbody></table>
|
||||
</td></tr></tbody></table></div>
|
||||
<!--[if mso | IE]>
|
||||
</td></tr></table>
|
||||
<![endif]-->
|
||||
</td></tr></tbody></table></div>
|
||||
<!--[if mso | IE]>
|
||||
</td></tr></table>
|
||||
<![endif]--></div>
|
||||
</body>
|
||||
</html>
|
||||
|
|
@ -1,302 +0,0 @@
|
|||
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
|
||||
<html data-editor-version="2" class="sg-campaigns" xmlns="http://www.w3.org/1999/xhtml">
|
||||
<head>
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1, minimum-scale=1, maximum-scale=1">
|
||||
<!--[if !mso]><!-->
|
||||
<meta http-equiv="X-UA-Compatible" content="IE=Edge">
|
||||
<!--<![endif]-->
|
||||
<!--[if (gte mso 9)|(IE)]>
|
||||
<xml>
|
||||
<o:OfficeDocumentSettings>
|
||||
<o:AllowPNG/>
|
||||
<o:PixelsPerInch>96</o:PixelsPerInch>
|
||||
</o:OfficeDocumentSettings>
|
||||
</xml>
|
||||
<![endif]-->
|
||||
<!--[if (gte mso 9)|(IE)]>
|
||||
<style type="text/css">
|
||||
body {width: 600px;margin: 0 auto;}
|
||||
table {border-collapse: collapse;}
|
||||
table, td {mso-table-lspace: 0pt;mso-table-rspace: 0pt;}
|
||||
img {-ms-interpolation-mode: bicubic;}
|
||||
</style>
|
||||
<![endif]-->
|
||||
<style type="text/css">
|
||||
body, p, div {
|
||||
font-family: arial,helvetica,sans-serif;
|
||||
font-size: 14px;
|
||||
}
|
||||
body {
|
||||
color: #000000;
|
||||
}
|
||||
body a {
|
||||
color: #1188E6;
|
||||
text-decoration: none;
|
||||
}
|
||||
p { margin: 0; padding: 0; }
|
||||
table.wrapper {
|
||||
width:100% !important;
|
||||
table-layout: fixed;
|
||||
-webkit-font-smoothing: antialiased;
|
||||
-webkit-text-size-adjust: 100%;
|
||||
-moz-text-size-adjust: 100%;
|
||||
-ms-text-size-adjust: 100%;
|
||||
}
|
||||
img.max-width {
|
||||
max-width: 100% !important;
|
||||
}
|
||||
.column.of-2 {
|
||||
width: 50%;
|
||||
}
|
||||
.column.of-3 {
|
||||
width: 33.333%;
|
||||
}
|
||||
.column.of-4 {
|
||||
width: 25%;
|
||||
}
|
||||
ul ul ul ul {
|
||||
list-style-type: disc !important;
|
||||
}
|
||||
ol ol {
|
||||
list-style-type: lower-roman !important;
|
||||
}
|
||||
ol ol ol {
|
||||
list-style-type: lower-latin !important;
|
||||
}
|
||||
ol ol ol ol {
|
||||
list-style-type: decimal !important;
|
||||
}
|
||||
@media screen and (max-width:480px) {
|
||||
.preheader .rightColumnContent,
|
||||
.footer .rightColumnContent {
|
||||
text-align: left !important;
|
||||
}
|
||||
.preheader .rightColumnContent div,
|
||||
.preheader .rightColumnContent span,
|
||||
.footer .rightColumnContent div,
|
||||
.footer .rightColumnContent span {
|
||||
text-align: left !important;
|
||||
}
|
||||
.preheader .rightColumnContent,
|
||||
.preheader .leftColumnContent {
|
||||
font-size: 80% !important;
|
||||
padding: 5px 0;
|
||||
}
|
||||
table.wrapper-mobile {
|
||||
width: 100% !important;
|
||||
table-layout: fixed;
|
||||
}
|
||||
img.max-width {
|
||||
height: auto !important;
|
||||
max-width: 100% !important;
|
||||
}
|
||||
a.bulletproof-button {
|
||||
display: block !important;
|
||||
width: auto !important;
|
||||
font-size: 80%;
|
||||
padding-left: 0 !important;
|
||||
padding-right: 0 !important;
|
||||
}
|
||||
.columns {
|
||||
width: 100% !important;
|
||||
}
|
||||
.column {
|
||||
display: block !important;
|
||||
width: 100% !important;
|
||||
padding-left: 0 !important;
|
||||
padding-right: 0 !important;
|
||||
margin-left: 0 !important;
|
||||
margin-right: 0 !important;
|
||||
}
|
||||
.social-icon-column {
|
||||
display: inline-block !important;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
<style>
|
||||
@media screen and (max-width:480px) {
|
||||
table\0 {
|
||||
width: 480px !important;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
<!--user entered Head Start--><!--End Head user entered-->
|
||||
</head>
|
||||
<body>
|
||||
<center class="wrapper" data-link-color="#1188E6" data-body-style="font-size:14px; font-family:arial,helvetica,sans-serif; color:#000000; background-color:#FFFFFF;">
|
||||
<div class="webkit">
|
||||
<table cellpadding="0" cellspacing="0" border="0" width="100%" class="wrapper" bgcolor="#FFFFFF">
|
||||
<tr>
|
||||
<td valign="top" bgcolor="#FFFFFF" width="100%">
|
||||
<table width="100%" role="content-container" class="outer" align="center" cellpadding="0" cellspacing="0" border="0">
|
||||
<tr>
|
||||
<td width="100%">
|
||||
<table width="100%" cellpadding="0" cellspacing="0" border="0">
|
||||
<tr>
|
||||
<td>
|
||||
<!--[if mso]>
|
||||
<center>
|
||||
<table><tr><td width="600">
|
||||
<![endif]-->
|
||||
<table width="100%" cellpadding="0" cellspacing="0" border="0" style="width:100%; max-width:600px;" align="center">
|
||||
<tr>
|
||||
<td role="modules-container" style="padding:0px 0px 0px 0px; color:#000000; text-align:left;" bgcolor="#FFFFFF" width="100%" align="left"><table class="module preheader preheader-hide" role="module" data-type="preheader" border="0" cellpadding="0" cellspacing="0" width="100%" style="display: none !important; mso-hide: all; visibility: hidden; opacity: 0; color: transparent; height: 0; width: 0;">
|
||||
<tr>
|
||||
<td role="module-content">
|
||||
<p></p>
|
||||
</td>
|
||||
</tr>
|
||||
</table><table class="module" role="module" data-type="code" border="0" cellpadding="0" cellspacing="0" width="100%" style="table-layout: fixed;" data-muid="xmBk5YWrK5pQFNFMyZSx2S">
|
||||
<tr>
|
||||
<td height="100%" valign="top" data-role="module-content"><!doctype html>
|
||||
<html lang="en" xmlns="http://www.w3.org/1999/xhtml">
|
||||
<head>
|
||||
<title>Welcome to Appsmith!</title>
|
||||
<!--[if !mso]><!-->
|
||||
<meta http-equiv="X-UA-Compatible" content="IE=edge">
|
||||
<!--<![endif]-->
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||
<style type="text/css">
|
||||
#outlook a{padding:0;}body{margin:0;padding:0;-webkit-text-size-adjust:100%;-ms-text-size-adjust:100%;}table,td{border-collapse:collapse;mso-table-lspace:0pt;mso-table-rspace:0pt;}img{border:0;height:auto;line-height:100%;outline:none;text-decoration:none;-ms-interpolation-mode:bicubic;}p{display:block;margin:0;}
|
||||
</style>
|
||||
<!--[if mso]> <noscript><xml><o:OfficeDocumentSettings><o:AllowPNG/><o:PixelsPerInch>96</o:PixelsPerInch></o:OfficeDocumentSettings></xml></noscript>
|
||||
<![endif]-->
|
||||
<!--[if lte mso 11]>
|
||||
<style type="text/css">
|
||||
.ogf{width:100% !important;}
|
||||
</style>
|
||||
<![endif]-->
|
||||
<!--[if !mso]><!-->
|
||||
<link href="https://fonts.googleapis.com/css?family=Inter:700" rel="stylesheet" type="text/css">
|
||||
<style type="text/css">
|
||||
|
||||
</style>
|
||||
<!--<![endif]-->
|
||||
<style type="text/css">
|
||||
@media only screen and (min-width:599px){.xc536{width:536px!important;max-width:536px;}.xc0{width:0px!important;max-width:0;}.xc16{width:16px!important;max-width:16px;}}
|
||||
</style>
|
||||
<style media="screen and (min-width:599px)">.moz-text-html .xc536{width:536px!important;max-width:536px;}.moz-text-html .xc0{width:0px!important;max-width:0;}.moz-text-html .xc16{width:16px!important;max-width:16px;}
|
||||
</style>
|
||||
<style type="text/css">
|
||||
@media only screen and (max-width:599px){table.fwm{width:100%!important;}td.fwm{width:auto!important;}}
|
||||
</style>
|
||||
<style type="text/css">
|
||||
u+.emailify a,#MessageViewBody a,a[x-apple-data-detectors]{color:inherit!important;text-decoration:none!important;font-size:inherit!important;font-family:inherit!important;font-weight:inherit!important;line-height:inherit!important;}span.MsoHyperlink{mso-style-priority:99;color:inherit;}span.MsoHyperlinkFollowed{mso-style-priority:99;color:inherit;}td.b .klaviyo-image-block{display:inline;vertical-align:middle;}
|
||||
@media only screen and (max-width:599px){.emailify{height:100%!important;margin:0!important;padding:0!important;width:100%!important;}u+.emailify .glist{margin-left:1em!important;}td.x{padding-left:0!important;padding-right:0!important;}.fwm img{max-width:100%!important;height:auto!important;}td.b.nw>table,td.b.nw a{width:auto!important;}td.stk{border:0!important;}br.sb{display:none!important;}.thd-1 .i-thumbnail{display:inline-block!important;height:auto!important;overflow:hidden!important;}.hd-1{display:block!important;height:auto!important;overflow:visible!important;}.ht-1{display:table!important;height:auto!important;overflow:visible!important;}.hr-1{display:table-row!important;height:auto!important;overflow:visible!important;}.hc-1{display:table-cell!important;height:auto!important;overflow:visible!important;}div.r.pr-16>table>tbody>tr>td,div.r.pr-16>div>table>tbody>tr>td{padding-right:16px!important}div.r.pl-16>table>tbody>tr>td,div.r.pl-16>div>table>tbody>tr>td{padding-left:16px!important}td.b.fw-1>table{width:100%!important}td.fw-1>table>tbody>tr>td>a{display:block!important;width:100%!important;padding-left:0!important;padding-right:0!important;}td.b.fw-1>table{width:100%!important}td.fw-1>table>tbody>tr>td{width:100%!important;padding-left:0!important;padding-right:0!important;}}
|
||||
</style>
|
||||
<meta name="color-scheme" content="light dark">
|
||||
<meta name="supported-color-schemes" content="light dark">
|
||||
<!--[if gte mso 9]>
|
||||
<style>li{text-indent:-1em;}
|
||||
</style>
|
||||
<![endif]-->
|
||||
</head>
|
||||
<body lang="en" class="emailify" style="mso-line-height-rule:exactly;word-spacing:normal;background-color:#d6d6d6;"><div class="bg" style="background-color:#d6d6d6;">
|
||||
<!--[if mso | IE]>
|
||||
<table align="center" border="0" cellpadding="0" cellspacing="0" class="r-outlook -outlook pr-16-outlook pl-16-outlook -outlook" role="none" style="width:600px;" width="600" bgcolor="#f8f8f8"><tr><td style="line-height:0;font-size:0;mso-line-height-rule:exactly;">
|
||||
<![endif]--><div class="r pr-16 pl-16" style="background:#f8f8f8;background-color:#f8f8f8;margin:0px auto;max-width:600px;">
|
||||
<table align="center" border="0" cellpadding="0" cellspacing="0" role="none" style="background:#f8f8f8;background-color:#f8f8f8;width:100%;"><tbody><tr><td style="border:none;direction:ltr;font-size:0;padding:32px 32px 8px 32px;text-align:left;">
|
||||
<!--[if mso | IE]>
|
||||
<table role="none" border="0" cellpadding="0" cellspacing="0"><tr><td class="m-outlook c-outlook -outlook -outlook" style="vertical-align:top;width:536px;">
|
||||
<![endif]--><div class="xc536 ogf m c" style="font-size:0;text-align:left;direction:ltr;display:inline-block;vertical-align:top;width:100%;">
|
||||
<table border="0" cellpadding="0" cellspacing="0" role="none" style="border:none;vertical-align:top;" width="100%"><tbody><tr><td align="center" class="d" style="font-size:0;padding:0;word-break:break-word;"><h1 style="border-top:solid 8px #f86a2b;font-size:1px;margin:0px auto;width:100%;"></h1>
|
||||
<!--[if mso | IE]>
|
||||
<table align="center" border="0" cellpadding="0" cellspacing="0" style="border-top:solid 8px #f86a2b;font-size:1px;margin:0px auto;width:536px;" role="none" width="536px"><tr><td style="height:0;line-height:0;">
|
||||
</td></tr></table>
|
||||
<![endif]-->
|
||||
</td></tr></tbody></table></div>
|
||||
<!--[if mso | IE]>
|
||||
</td><td class="g-outlook" style="vertical-align:top;width:0;">
|
||||
<![endif]--><div class="xc0 ogf g" style="font-size:0;text-align:left;direction:ltr;display:inline-block;vertical-align:top;width:100%;">
|
||||
<table border="0" cellpadding="0" cellspacing="0" role="none" width="100%"><tbody><tr><td style="vertical-align:top;padding:0;">
|
||||
<table border="0" cellpadding="0" cellspacing="0" role="none" width="100%"><tbody></tbody></table>
|
||||
</td></tr></tbody></table></div>
|
||||
<!--[if mso | IE]>
|
||||
</td><td class="c-outlook -outlook -outlook" style="vertical-align:top;width:536px;">
|
||||
<![endif]--><div class="xc536 ogf c" style="font-size:0;text-align:left;direction:ltr;display:inline-block;vertical-align:top;width:100%;">
|
||||
<table border="0" cellpadding="0" cellspacing="0" role="none" width="100%"><tbody><tr><td style="background-color:#fffffe;border:none;vertical-align:top;padding:40px 24px 24px 24px;">
|
||||
<table border="0" cellpadding="0" cellspacing="0" role="none" width="100%"><tbody><tr><td align="center" class="i m" style="font-size:0;padding:0;padding-bottom:16px;word-break:break-word;">
|
||||
<table border="0" cellpadding="0" cellspacing="0" role="none" style="border-collapse:collapse;border-spacing:0;"><tbody><tr><td style="width:200px;"> <img alt="" height="auto" src="https://assets.appsmith.com/appsmith-logo-no-margin.png" style="border:0;display:block;outline:none;text-decoration:none;height:auto;width:100%;font-size:13px;" title="" width="200">
|
||||
</td></tr></tbody></table>
|
||||
</td></tr><tr><td class="s m" style="font-size:0;padding:0;padding-bottom:16px;word-break:break-word;"><div style="height:1px;line-height:1px;"> </div>
|
||||
</td></tr><tr><td align="center" class="x m" style="font-size:0;padding-bottom:16px;word-break:break-word;"><div style="text-align:center;"><p style="Margin:0;text-align:center;"><span style="font-size:20px;font-family:SF Pro Text,Arial,sans-serif;font-weight:600;color:#000000;line-height:24px;">Welcome to Appsmith</span></p></div>
|
||||
</td></tr><tr><td align="center" class="x m" style="font-size:0;padding-bottom:16px;word-break:break-word;"><div style="text-align:center;"><p style="Margin:0;text-align:center;"><span style="font-size:16px;font-family:SF Pro Text,Arial,sans-serif;font-weight:400;color:#000000;line-height:24px;">You're now part of a developer community using appsmith to save hundreds of hours building internal tools! 🎉
|
||||
</span></p></div></td></tr>
|
||||
<tr><td align="center" class="x m" style="font-size:0;padding-bottom:16px;word-break:break-word;"><div style="text-align:center;"><p style="Margin:0;text-align:center;"><span style="font-size:16px;font-family:SF Pro Text,Arial,sans-serif;font-weight:400;color:#000000;line-height:24px;">If you'd like some help getting started, I'd be happy to get on a call & walk you through building your first app! <a href="http://bit.ly/appsmith-live-demo">Schedule a Call</a> 📅</span></p></div>
|
||||
</td></tr>
|
||||
<tr><td align="center" class="x m" style="font-size:0;padding-bottom:16px;word-break:break-word;"><div style="text-align:center;"><p style="Margin:0;text-align:center;"><span style="font-size:16px;font-family:SF Pro Text,Arial,sans-serif;font-weight:400;color:#000000;line-height:24px;">We're a fun, active group of developers, and we'd love for you to join us on <a href="http://bit.ly/appsmith-discord">Discord</a></span></p></div>
|
||||
</td></tr>
|
||||
<tr><td class="s m" style="font-size:0;padding:0;padding-bottom:16px;word-break:break-word;"><div style="height:4px;line-height:4px;"> </div>
|
||||
</td></tr><tr><td align="center" class="b fw-1" style="font-size:0;padding:0;padding-bottom:0;word-break:break-word;">
|
||||
<table border="0" cellpadding="0" cellspacing="0" role="none" style="border-collapse:separate;width:135px;line-height:100%;"><tbody><tr><td align="center" bgcolor="#f86a2b" role="none" style="border:none;border-radius:4px 4px 4px 4px;cursor:auto;mso-padding-alt:12px 0px 12px 0px;background:#f86a2b;" valign="middle"> <a href="{{primaryLinkUrl}}" style="display:inline-block;width:135px;background:#f86a2b;color:#ffffff;font-family:Inter,Arial,sans-serif;font-size:13px;font-weight:normal;line-height:100%;margin:0;text-decoration:none;text-transform:none;padding:12px 0px 12px 0px;mso-padding-alt:0;border-radius:4px 4px 4px 4px;" target="_blank"> <span style="font-size:14px;font-family:Inter,Arial,sans-serif;font-weight:700;color:#ffffff;line-height:17px;">Go To Dashboard</span></a>
|
||||
</td></tr></tbody></table>
|
||||
</td></tr></tbody></table>
|
||||
</td></tr></tbody></table></div>
|
||||
<!--[if mso | IE]>
|
||||
</td></tr></table>
|
||||
<![endif]-->
|
||||
</td></tr></tbody></table></div>
|
||||
<!--[if mso | IE]>
|
||||
</td></tr></table>
|
||||
<table align="center" border="0" cellpadding="0" cellspacing="0" class="r-outlook -outlook pr-16-outlook pl-16-outlook -outlook" role="none" style="width:600px;" width="600" bgcolor="#f8f8f8"><tr><td style="line-height:0;font-size:0;mso-line-height-rule:exactly;">
|
||||
<![endif]--><div class="r pr-16 pl-16" style="background:#f8f8f8;background-color:#f8f8f8;margin:0px auto;max-width:600px;">
|
||||
<table align="center" border="0" cellpadding="0" cellspacing="0" role="none" style="background:#f8f8f8;background-color:#f8f8f8;width:100%;"><tbody><tr><td style="border:none;direction:ltr;font-size:0;padding:16px 32px 16px 32px;text-align:left;">
|
||||
<!--[if mso | IE]>
|
||||
<table role="none" border="0" cellpadding="0" cellspacing="0"><tr><td class="m-outlook c-outlook -outlook -outlook" style="vertical-align:top;width:536px;">
|
||||
<![endif]--><div class="xc536 ogf m c" style="font-size:0;text-align:left;direction:ltr;display:inline-block;vertical-align:top;width:100%;">
|
||||
<table border="0" cellpadding="0" cellspacing="0" role="none" style="border:none;vertical-align:top;" width="100%"><tbody><tr><td align="center" class="d" style="font-size:0;padding:0;word-break:break-word;"><p style="border-top:solid 1px #cccccc;font-size:1px;margin:0px auto;width:100%;"></p>
|
||||
<!--[if mso | IE]>
|
||||
<table align="center" border="0" cellpadding="0" cellspacing="0" style="border-top:solid 1px #cccccc;font-size:1px;margin:0px auto;width:536px;" role="none" width="536px"><tr><td style="height:0;line-height:0;">
|
||||
</td></tr></table>
|
||||
<![endif]-->
|
||||
</td></tr></tbody></table></div>
|
||||
<!--[if mso | IE]>
|
||||
</td><td class="g-outlook" style="vertical-align:top;width:16px;">
|
||||
<![endif]--><div class="xc16 ogf g" style="font-size:0;text-align:left;direction:ltr;display:inline-block;vertical-align:top;width:100%;">
|
||||
<table border="0" cellpadding="0" cellspacing="0" role="none" width="100%"><tbody><tr><td style="vertical-align:top;padding:0;">
|
||||
<table border="0" cellpadding="0" cellspacing="0" role="none" width="100%"><tbody></tbody></table>
|
||||
</td></tr></tbody></table></div>
|
||||
<!--[if mso | IE]>
|
||||
</td><td class="c-outlook -outlook -outlook" style="vertical-align:top;width:536px;">
|
||||
<![endif]--><div class="xc536 ogf c" style="font-size:0;text-align:left;direction:ltr;display:inline-block;vertical-align:top;width:100%;">
|
||||
<table border="0" cellpadding="0" cellspacing="0" role="none" width="100%"><tbody><tr><td style="border:none;vertical-align:top;padding:0px 12px 0px 12px;">
|
||||
<table border="0" cellpadding="0" cellspacing="0" role="none" width="100%"><tbody><tr><td align="left" class="i fw-1 m" style="font-size:0;padding:0;padding-bottom:8px;word-break:break-word;">
|
||||
<table border="0" cellpadding="0" cellspacing="0" role="none" style="border-collapse:collapse;border-spacing:0;" class="fwm"><tbody><tr><td style="width:512px;" class="fwm"> <img alt="" height="auto" src="https://emailify.b-cdn.net/f76e7fcbed28d8e5b3acc27c5109a06e.png" style="border:0;display:block;outline:none;text-decoration:none;height:auto;width:100%;font-size:13px;" title="" width="512">
|
||||
</td></tr></tbody></table>
|
||||
</td></tr><tr><td align="center" class="x" style="font-size:0;padding-bottom:0;word-break:break-word;"><div style="text-align:center;"><p style="Margin:0;text-align:center;"><span style="font-size:14px;font-family:SF Pro Text,Arial,sans-serif;font-weight:400;color:#b3b3b3;line-height:22px;">Appsmith is an open source framework that helps developer and companies to build powerful internal tools.</span></p></div>
|
||||
</td></tr></tbody></table>
|
||||
</td></tr></tbody></table></div>
|
||||
<!--[if mso | IE]>
|
||||
</td></tr></table>
|
||||
<![endif]-->
|
||||
</td></tr></tbody></table></div>
|
||||
<!--[if mso | IE]>
|
||||
</td></tr></table>
|
||||
<![endif]--></div>
|
||||
</body>
|
||||
</html></td>
|
||||
</tr>
|
||||
</table></td>
|
||||
</tr>
|
||||
</table>
|
||||
<!--[if mso]>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
</center>
|
||||
<![endif]-->
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
</div>
|
||||
</center>
|
||||
</body>
|
||||
</html>
|
||||
|
|
@ -55,10 +55,8 @@ import java.time.Instant;
|
|||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Optional;
|
||||
import java.util.Set;
|
||||
import java.util.UUID;
|
||||
|
||||
import static com.appsmith.server.acl.AclPermission.MANAGE_USERS;
|
||||
import static com.appsmith.server.acl.AclPermission.RESET_PASSWORD_USERS;
|
||||
|
|
@ -125,43 +123,6 @@ public class UserServiceTest {
|
|||
public void setup() {
|
||||
userMono = userService.findByEmail("usertest@usertest.com");
|
||||
}
|
||||
|
||||
// Test if email params are updating correctly
|
||||
@Test
|
||||
public void checkEmailParamsForExistingUser() {
|
||||
Workspace workspace = new Workspace();
|
||||
workspace.setName("UserServiceTest Update Org");
|
||||
workspace.setId(UUID.randomUUID().toString());
|
||||
|
||||
User inviter = new User();
|
||||
inviter.setName("inviterUserToApplication");
|
||||
|
||||
String inviteUrl = "http://localhost:8080";
|
||||
String expectedUrl = inviteUrl + "/applications#" + workspace.getId();
|
||||
|
||||
Map<String, String> params = userService.getEmailParams(workspace, inviter, inviteUrl, false);
|
||||
assertEquals(expectedUrl, params.get("primaryLinkUrl"));
|
||||
assertEquals("inviterUserToApplication", params.get("inviterFirstName"));
|
||||
assertEquals("UserServiceTest Update Org", params.get("inviterWorkspaceName"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void checkEmailParamsForNewUser() {
|
||||
Workspace workspace = new Workspace();
|
||||
workspace.setId(UUID.randomUUID().toString());
|
||||
workspace.setName("UserServiceTest Update Org");
|
||||
|
||||
User inviter = new User();
|
||||
inviter.setName("inviterUserToApplication");
|
||||
|
||||
String inviteUrl = "http://localhost:8080";
|
||||
|
||||
Map<String, String> params = userService.getEmailParams(workspace, inviter, inviteUrl, true);
|
||||
assertEquals(inviteUrl, params.get("primaryLinkUrl"));
|
||||
assertEquals("inviterUserToApplication", params.get("inviterFirstName"));
|
||||
assertEquals("UserServiceTest Update Org", params.get("inviterWorkspaceName"));
|
||||
}
|
||||
|
||||
// Test the update workspace flow.
|
||||
@Test
|
||||
public void updateInvalidUserWithAnything() {
|
||||
|
|
@ -388,9 +349,7 @@ public class UserServiceTest {
|
|||
signUpUser.setEmail(newUserEmail);
|
||||
signUpUser.setPassword("123456");
|
||||
|
||||
Mono<User> invitedUserSignUpMono = userService
|
||||
.createUserAndSendEmail(signUpUser, "http://localhost:8080")
|
||||
.map(UserSignupDTO::getUser);
|
||||
Mono<User> invitedUserSignUpMono = userService.createUser(signUpUser).map(UserSignupDTO::getUser);
|
||||
|
||||
StepVerifier.create(invitedUserSignUpMono)
|
||||
.assertNext(user -> {
|
||||
|
|
@ -563,24 +522,6 @@ public class UserServiceTest {
|
|||
.verifyComplete();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void createUserAndSendEmail_WhenUserExistsWithEmailInOtherCase_ThrowsException() {
|
||||
User existingUser = new User();
|
||||
existingUser.setEmail("abcd@gmail.com");
|
||||
userRepository.save(existingUser).block();
|
||||
|
||||
User newUser = new User();
|
||||
newUser.setEmail("abCd@gmail.com"); // same as above except c in uppercase
|
||||
newUser.setSource(LoginSource.FORM);
|
||||
newUser.setPassword("abcdefgh");
|
||||
Mono<User> userAndSendEmail =
|
||||
userService.createUserAndSendEmail(newUser, null).map(UserSignupDTO::getUser);
|
||||
|
||||
StepVerifier.create(userAndSendEmail)
|
||||
.expectErrorMessage(AppsmithError.USER_ALREADY_EXISTS_SIGNUP.getMessage(existingUser.getEmail()))
|
||||
.verify();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void forgotPasswordTokenGenerate_AfterTrying3TimesIn24Hours_ThrowsException() {
|
||||
String testEmail = "test-email-for-password-reset";
|
||||
|
|
|
|||
|
|
@ -0,0 +1,192 @@
|
|||
package com.appsmith.server.services.ce;
|
||||
|
||||
import com.appsmith.server.constants.FieldName;
|
||||
import com.appsmith.server.domains.PermissionGroup;
|
||||
import com.appsmith.server.domains.Tenant;
|
||||
import com.appsmith.server.domains.TenantConfiguration;
|
||||
import com.appsmith.server.domains.User;
|
||||
import com.appsmith.server.domains.Workspace;
|
||||
import com.appsmith.server.notifications.EmailSender;
|
||||
import com.appsmith.server.services.TenantService;
|
||||
import org.junit.jupiter.api.BeforeEach;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.junit.jupiter.api.extension.ExtendWith;
|
||||
import org.mockito.Mock;
|
||||
import org.mockito.MockitoAnnotations;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.boot.test.context.SpringBootTest;
|
||||
import org.springframework.test.context.junit.jupiter.SpringExtension;
|
||||
import reactor.core.publisher.Mono;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
import static com.appsmith.server.constants.ce.EmailConstantsCE.EMAIL_ROLE_ADMINISTRATOR_TEXT;
|
||||
import static com.appsmith.server.constants.ce.EmailConstantsCE.FORGOT_PASSWORD_EMAIL_SUBJECT;
|
||||
import static com.appsmith.server.constants.ce.EmailConstantsCE.FORGOT_PASSWORD_TEMPLATE_CE;
|
||||
import static com.appsmith.server.constants.ce.EmailConstantsCE.INSTANCE_ADMIN_INVITE_EMAIL_SUBJECT;
|
||||
import static com.appsmith.server.constants.ce.EmailConstantsCE.INSTANCE_ADMIN_INVITE_EMAIL_TEMPLATE;
|
||||
import static com.appsmith.server.constants.ce.EmailConstantsCE.INSTANCE_NAME;
|
||||
import static com.appsmith.server.constants.ce.EmailConstantsCE.INVITER_FIRST_NAME;
|
||||
import static com.appsmith.server.constants.ce.EmailConstantsCE.INVITER_WORKSPACE_NAME;
|
||||
import static com.appsmith.server.constants.ce.EmailConstantsCE.PRIMARY_LINK_TEXT;
|
||||
import static com.appsmith.server.constants.ce.EmailConstantsCE.PRIMARY_LINK_URL;
|
||||
import static com.appsmith.server.constants.ce.EmailConstantsCE.RESET_URL;
|
||||
import static com.appsmith.server.constants.ce.EmailConstantsCE.WORKSPACE_EMAIL_SUBJECT_FOR_NEW_USER;
|
||||
import static graphql.Assert.assertTrue;
|
||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||
import static org.mockito.ArgumentMatchers.anyMap;
|
||||
import static org.mockito.ArgumentMatchers.anyString;
|
||||
import static org.mockito.Mockito.doAnswer;
|
||||
|
||||
@SpringBootTest
|
||||
@ExtendWith(SpringExtension.class)
|
||||
class EmailServiceCEImplTest {
|
||||
|
||||
@Autowired
|
||||
TenantService tenantService;
|
||||
|
||||
@Mock
|
||||
EmailSender mockEmailSender;
|
||||
|
||||
private EmailServiceCE emailService;
|
||||
|
||||
@BeforeEach
|
||||
public void setup() {
|
||||
MockitoAnnotations.openMocks(this);
|
||||
TenantConfiguration tenantConfiguration = new TenantConfiguration();
|
||||
|
||||
Tenant tenant = tenantService.getDefaultTenant().block();
|
||||
assert tenant != null;
|
||||
tenant.setTenantConfiguration(tenantConfiguration);
|
||||
|
||||
this.emailService = new EmailServiceCEImpl(mockEmailSender, tenantService);
|
||||
}
|
||||
|
||||
@Test
|
||||
void sendForgotPasswordEmail() {
|
||||
String email = "test@example.com";
|
||||
String resetUrl = "http://example.com/reset";
|
||||
String originHeader = "http://example.com";
|
||||
|
||||
Map<String, String> expectedParams = new HashMap<>();
|
||||
expectedParams.put(RESET_URL, resetUrl);
|
||||
expectedParams.put(INSTANCE_NAME, "Appsmith");
|
||||
|
||||
doAnswer(invocation -> {
|
||||
String to = invocation.getArgument(0);
|
||||
String subject = invocation.getArgument(1);
|
||||
String text = invocation.getArgument(2);
|
||||
Map<String, String> params = invocation.getArgument(3);
|
||||
|
||||
assertEquals(email, to);
|
||||
assertEquals(
|
||||
String.format(FORGOT_PASSWORD_EMAIL_SUBJECT, expectedParams.get(INSTANCE_NAME)), subject);
|
||||
assertEquals(FORGOT_PASSWORD_TEMPLATE_CE, text);
|
||||
assertEquals(expectedParams, params);
|
||||
|
||||
return Mono.just(true);
|
||||
})
|
||||
.when(mockEmailSender)
|
||||
.sendMail(anyString(), anyString(), anyString(), anyMap());
|
||||
|
||||
emailService.sendForgotPasswordEmail(email, resetUrl, originHeader).block();
|
||||
}
|
||||
|
||||
@Test
|
||||
void sendInviteUserToWorkspaceEmail() {
|
||||
User invitingUser = new User();
|
||||
String invitingUserMail = "a@abc.com";
|
||||
invitingUser.setEmail(invitingUserMail);
|
||||
|
||||
User invitedUser = new User();
|
||||
String invitedUserMail = "b@abc.com";
|
||||
invitedUser.setEmail(invitedUserMail);
|
||||
|
||||
Workspace workspace = new Workspace();
|
||||
String workspaceName = "testWorkspace";
|
||||
String workspaceId = "testWorkspaceId";
|
||||
workspace.setName(workspaceName);
|
||||
workspace.setId(workspaceId);
|
||||
|
||||
PermissionGroup permissionGroup = new PermissionGroup();
|
||||
String permissionGroupName = FieldName.ADMINISTRATOR + "role";
|
||||
permissionGroup.setName(permissionGroupName);
|
||||
|
||||
boolean isNewUser = true;
|
||||
|
||||
String originHeader = "http://example.com";
|
||||
|
||||
Map<String, String> expectedParams = new HashMap<>();
|
||||
expectedParams.put(INVITER_WORKSPACE_NAME, workspaceName);
|
||||
expectedParams.put(INVITER_FIRST_NAME, invitingUserMail);
|
||||
expectedParams.put(FieldName.ROLE, permissionGroupName);
|
||||
expectedParams.put(INSTANCE_NAME, "Appsmith");
|
||||
|
||||
doAnswer(invocation -> {
|
||||
String to = invocation.getArgument(0);
|
||||
String subject = invocation.getArgument(1);
|
||||
String text = invocation.getArgument(2);
|
||||
Map<String, String> params = invocation.getArgument(3);
|
||||
|
||||
assertEquals(invitedUser.getEmail(), to);
|
||||
assertEquals(String.format(WORKSPACE_EMAIL_SUBJECT_FOR_NEW_USER, workspace.getName()), subject);
|
||||
assertTrue(params.containsKey(PRIMARY_LINK_URL));
|
||||
assertTrue(params.containsKey(PRIMARY_LINK_TEXT));
|
||||
assertEquals(expectedParams.get(INSTANCE_NAME), params.get(INSTANCE_NAME));
|
||||
assertEquals(expectedParams.get(INVITER_WORKSPACE_NAME), params.get(INVITER_WORKSPACE_NAME));
|
||||
assertEquals(expectedParams.get(INVITER_FIRST_NAME), params.get(INVITER_FIRST_NAME));
|
||||
assertEquals(EMAIL_ROLE_ADMINISTRATOR_TEXT, params.get(FieldName.ROLE));
|
||||
|
||||
return Mono.just(true);
|
||||
})
|
||||
.when(mockEmailSender)
|
||||
.sendMail(anyString(), anyString(), anyString(), anyMap());
|
||||
|
||||
emailService
|
||||
.sendInviteUserToWorkspaceEmail(
|
||||
invitingUser, invitedUser, workspace, permissionGroup, originHeader, isNewUser)
|
||||
.block();
|
||||
}
|
||||
|
||||
@Test
|
||||
void testSendInstanceAdminInviteEmail() {
|
||||
User invitingUser = new User();
|
||||
String invitingUserMail = "a@abc.com";
|
||||
invitingUser.setEmail(invitingUserMail);
|
||||
|
||||
User invitedUser = new User();
|
||||
String invitedUserMail = "b@abc.com";
|
||||
invitedUser.setEmail(invitedUserMail);
|
||||
|
||||
String originHeader = "http://example.com";
|
||||
|
||||
Map<String, String> expectedParams = new HashMap<>();
|
||||
expectedParams.put(INSTANCE_NAME, "Appsmith");
|
||||
expectedParams.put(INVITER_FIRST_NAME, invitingUserMail);
|
||||
|
||||
doAnswer(invocation -> {
|
||||
String to = invocation.getArgument(0);
|
||||
String subject = invocation.getArgument(1);
|
||||
String text = invocation.getArgument(2);
|
||||
Map<String, String> params = invocation.getArgument(3);
|
||||
|
||||
assertEquals(invitedUser.getEmail(), to);
|
||||
assertEquals(
|
||||
String.format(INSTANCE_ADMIN_INVITE_EMAIL_SUBJECT, expectedParams.get(INSTANCE_NAME)),
|
||||
subject);
|
||||
assertEquals(INSTANCE_ADMIN_INVITE_EMAIL_TEMPLATE, text);
|
||||
assertEquals(expectedParams.get(INVITER_FIRST_NAME), params.get(INVITER_FIRST_NAME));
|
||||
assertTrue(params.containsKey(PRIMARY_LINK_URL));
|
||||
assertTrue(params.containsKey(PRIMARY_LINK_TEXT));
|
||||
|
||||
return Mono.just(true);
|
||||
})
|
||||
.when(mockEmailSender)
|
||||
.sendMail(anyString(), anyString(), anyString(), anyMap());
|
||||
|
||||
emailService
|
||||
.sendInstanceAdminInviteEmail(invitedUser, invitingUser, originHeader, true)
|
||||
.block();
|
||||
}
|
||||
}
|
||||
|
|
@ -12,6 +12,7 @@ import com.appsmith.server.notifications.EmailSender;
|
|||
import com.appsmith.server.repositories.UserRepository;
|
||||
import com.appsmith.server.services.AnalyticsService;
|
||||
import com.appsmith.server.services.ConfigService;
|
||||
import com.appsmith.server.services.EmailService;
|
||||
import com.appsmith.server.services.PermissionGroupService;
|
||||
import com.appsmith.server.services.SessionUserService;
|
||||
import com.appsmith.server.services.TenantService;
|
||||
|
|
@ -90,6 +91,9 @@ public class EnvManagerTest {
|
|||
@MockBean
|
||||
private ObjectMapper objectMapper;
|
||||
|
||||
@MockBean
|
||||
private EmailService emailService;
|
||||
|
||||
@BeforeEach
|
||||
public void setup() {
|
||||
envManager = new EnvManagerImpl(
|
||||
|
|
@ -107,7 +111,8 @@ public class EnvManagerTest {
|
|||
configService,
|
||||
userUtils,
|
||||
tenantService,
|
||||
objectMapper);
|
||||
objectMapper,
|
||||
emailService);
|
||||
}
|
||||
|
||||
@Test
|
||||
|
|
|
|||
|
|
@ -10,6 +10,7 @@ import com.appsmith.server.helpers.UserUtils;
|
|||
import com.appsmith.server.services.AnalyticsService;
|
||||
import com.appsmith.server.services.CaptchaService;
|
||||
import com.appsmith.server.services.ConfigService;
|
||||
import com.appsmith.server.services.EmailService;
|
||||
import com.appsmith.server.services.UserDataService;
|
||||
import com.appsmith.server.services.UserService;
|
||||
import org.junit.jupiter.api.BeforeEach;
|
||||
|
|
@ -57,6 +58,9 @@ public class UserSignupTest {
|
|||
@MockBean
|
||||
private NetworkUtils networkUtils;
|
||||
|
||||
@MockBean
|
||||
private EmailService emailService;
|
||||
|
||||
private UserSignup userSignup;
|
||||
|
||||
@BeforeEach
|
||||
|
|
@ -71,7 +75,8 @@ public class UserSignupTest {
|
|||
envManager,
|
||||
commonConfig,
|
||||
userUtils,
|
||||
networkUtils);
|
||||
networkUtils,
|
||||
emailService);
|
||||
}
|
||||
|
||||
private String createRandomString(int length) {
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user