diff --git a/app/assets/stylesheets/components/SiteSettings/Invitations/index.scss b/app/assets/stylesheets/components/SiteSettings/Invitations/index.scss index 9b42c2a3..bce9f29b 100644 --- a/app/assets/stylesheets/components/SiteSettings/Invitations/index.scss +++ b/app/assets/stylesheets/components/SiteSettings/Invitations/index.scss @@ -84,9 +84,13 @@ div.invitationInfo { @extend .d-flex; - span.invitationAcceptedAt, span.invitationSentAt { + span.invitationAcceptedAt, span.invitationSentAt, span.invitationExpired { @extend .align-self-center, .mutedText; } + + span.invitationExpired { + @extend .text-danger; + } } } } diff --git a/app/controllers/invitations_controller.rb b/app/controllers/invitations_controller.rb index 8db5cfa5..da218f17 100644 --- a/app/controllers/invitations_controller.rb +++ b/app/controllers/invitations_controller.rb @@ -56,7 +56,6 @@ class InvitationsController < ApplicationController render json: {}, status: :ok end - private def invitation_params @@ -66,4 +65,4 @@ class InvitationsController < ApplicationController invitation.require(:body) end end -end \ No newline at end of file +end diff --git a/app/controllers/registrations_controller.rb b/app/controllers/registrations_controller.rb index 5888feb7..17963bf3 100644 --- a/app/controllers/registrations_controller.rb +++ b/app/controllers/registrations_controller.rb @@ -14,12 +14,11 @@ class RegistrationsController < Devise::RegistrationsController # Handle invitations is_invitation = sign_up_params[:invitation_token].present? - is_invitation_valid = true invitation = nil if is_invitation invitation = Invitation.find_by(email: email) - if invitation.nil? || invitation.token_digest != Digest::SHA256.hexdigest(sign_up_params[:invitation_token]) || invitation.accepted_at.present? + if invitation.nil? || invitation.expired? || invitation.token_digest != Digest::SHA256.hexdigest(sign_up_params[:invitation_token]) || invitation.accepted_at.present? flash[:alert] = t('errors.unauthorized') redirect_to new_user_registration_path and return end diff --git a/app/javascript/components/SiteSettings/Invitations/index.tsx b/app/javascript/components/SiteSettings/Invitations/index.tsx index efb67793..c19d4666 100644 --- a/app/javascript/components/SiteSettings/Invitations/index.tsx +++ b/app/javascript/components/SiteSettings/Invitations/index.tsx @@ -10,7 +10,7 @@ import buildRequestHeaders from '../../../helpers/buildRequestHeaders'; import HttpStatus from '../../../constants/http_status'; import { isValidEmail } from '../../../helpers/regex'; import IInvitation from '../../../interfaces/IInvitation'; -import friendlyDate from '../../../helpers/datetime'; +import friendlyDate, { fromRailsStringToJavascriptDate, nMonthsAgo } from '../../../helpers/datetime'; import ActionLink from '../../common/ActionLink'; import { TestIcon } from '../../common/Icons'; @@ -229,9 +229,14 @@ const Invitations = ({ siteName, invitations, currentUserEmail, authenticityToke { I18n.t('site_settings.invitations.accepted_at', { when: friendlyDate(invitation.accepted_at) }) } : - - { I18n.t('site_settings.invitations.sent_at', { when: friendlyDate(invitation.updated_at) }) } - + fromRailsStringToJavascriptDate(invitation.updated_at) > nMonthsAgo(3) ? + + { I18n.t('site_settings.invitations.sent_at', { when: friendlyDate(invitation.updated_at) }) } + + : + + { I18n.t('site_settings.invitations.expired') } + } @@ -243,4 +248,4 @@ const Invitations = ({ siteName, invitations, currentUserEmail, authenticityToke ); }; -export default Invitations; \ No newline at end of file +export default Invitations; diff --git a/app/javascript/helpers/datetime.ts b/app/javascript/helpers/datetime.ts index 02f00799..820bc81c 100644 --- a/app/javascript/helpers/datetime.ts +++ b/app/javascript/helpers/datetime.ts @@ -47,4 +47,19 @@ export const fromRailsStringToJavascriptDate = date => { export const fromJavascriptDateToRailsString = (date: Date) => { return date.toJSON(); +} + +export const nMonthsAgo = (n: number) => { + const currentDate = new Date(); + + return new Date( + Date.UTC( + currentDate.getFullYear(), + currentDate.getMonth() - n, + currentDate.getDate(), + currentDate.getHours(), + currentDate.getMinutes(), + currentDate.getSeconds() + ) + ); } \ No newline at end of file diff --git a/app/models/invitation.rb b/app/models/invitation.rb index 67b3ac5e..ad13f69f 100644 --- a/app/models/invitation.rb +++ b/app/models/invitation.rb @@ -1,3 +1,9 @@ class Invitation < ApplicationRecord include TenantOwnable + + belongs_to :tenant + + def expired? + updated_at <= 3.months.ago + end end diff --git a/config/locales/en.yml b/config/locales/en.yml index bc131b3b..03a9d87a 100644 --- a/config/locales/en.yml +++ b/config/locales/en.yml @@ -272,6 +272,7 @@ en: accepted: 'Accepted' sent_at: 'Sent %{when}' accepted_at: 'Accepted %{when}' + expired: 'Expired' appearance: title: 'Appearance' learn_more: 'Learn how to customize appearance'