diff --git a/.rubocop.yml b/.rubocop.yml new file mode 100644 index 0000000..3211f2f --- /dev/null +++ b/.rubocop.yml @@ -0,0 +1,3 @@ +inherit_from: .rubocop_todo.yml +AllCops: + SuggestExtensions: false diff --git a/.rubocop_todo.yml b/.rubocop_todo.yml new file mode 100644 index 0000000..e01e0c8 --- /dev/null +++ b/.rubocop_todo.yml @@ -0,0 +1,371 @@ +# This configuration was generated by +# `rubocop --auto-gen-config` +# on 2021-01-15 10:55:07 UTC using RuboCop version 1.7.0. +# The point is for the user to remove these configuration records +# one by one as the offenses are removed from the code base. +# Note that changes in the inspected code, or installation of new +# versions of RuboCop, may require this file to be generated again. + +# Offense count: 2 +# Cop supports --auto-correct. +# Configuration parameters: TreatCommentsAsGroupSeparators, ConsiderPunctuation, Include. +# Include: **/*.gemfile, **/Gemfile, **/gems.rb +Bundler/OrderedGems: + Exclude: + - 'Gemfile' + +# Offense count: 2 +# Cop supports --auto-correct. +# Configuration parameters: EnforcedStyle, IndentationWidth. +# SupportedStyles: with_first_argument, with_fixed_indentation +Layout/ArgumentAlignment: + Exclude: + - 'bin/webpack' + - 'bin/webpack-dev-server' + +# Offense count: 6 +# Cop supports --auto-correct. +Layout/EmptyLineAfterGuardClause: + Exclude: + - 'bin/bundle' + +# Offense count: 1 +# Cop supports --auto-correct. +Layout/EmptyLines: + Exclude: + - 'app/controllers/api/v1/users_controller.rb' + +# Offense count: 1 +# Cop supports --auto-correct. +# Configuration parameters: EnforcedStyle. +# SupportedStyles: around, only_before +Layout/EmptyLinesAroundAccessModifier: + Exclude: + - 'app/controllers/api/v1/users_controller.rb' + +# Offense count: 2 +# Cop supports --auto-correct. +# Configuration parameters: IndentationWidth. +# SupportedStyles: special_inside_parentheses, consistent, align_braces +Layout/FirstHashElementIndentation: + EnforcedStyle: consistent + +# Offense count: 1 +# Cop supports --auto-correct. +# Configuration parameters: Width, IgnoredPatterns. +Layout/IndentationWidth: + Exclude: + - 'app/controllers/api/v1/users_controller.rb' + +# Offense count: 3 +# Cop supports --auto-correct. +# Configuration parameters: AllowDoxygenCommentStyle, AllowGemfileRubyComment. +Layout/LeadingCommentSpace: + Exclude: + - 'Gemfile' + - 'test/controllers/api/v1/users_controller_test.rb' + +# Offense count: 1 +# Cop supports --auto-correct. +Layout/LeadingEmptyLines: + Exclude: + - 'config/initializers/truemail.rb' + +# Offense count: 1 +# Cop supports --auto-correct. +# Configuration parameters: EnforcedStyle, IndentationWidth. +# SupportedStyles: aligned, indented +Layout/MultilineOperationIndentation: + Exclude: + - 'bin/bundle' + +# Offense count: 2 +# Cop supports --auto-correct. +Layout/SpaceAfterColon: + Exclude: + - 'app/controllers/api/v1/users_controller.rb' + +# Offense count: 2 +# Cop supports --auto-correct. +Layout/SpaceAfterComma: + Exclude: + - 'app/controllers/api/v1/users_controller.rb' + - 'app/models/user.rb' + +# Offense count: 1 +# Cop supports --auto-correct. +Layout/SpaceAroundKeyword: + Exclude: + - 'app/controllers/api/v1/users_controller.rb' + +# Offense count: 8 +# Cop supports --auto-correct. +# Configuration parameters: AllowForAlignment, EnforcedStyleForExponentOperator. +# SupportedStylesForExponentOperator: space, no_space +Layout/SpaceAroundOperators: + Exclude: + - 'app/controllers/api/v1/users_controller.rb' + +# Offense count: 4 +# Cop supports --auto-correct. +# Configuration parameters: EnforcedStyle, EnforcedStyleForEmptyBrackets. +# SupportedStyles: space, no_space, compact +# SupportedStylesForEmptyBrackets: space, no_space +Layout/SpaceInsideArrayLiteralBrackets: + Exclude: + - 'db/migrate/20210102105504_create_active_storage_tables.active_storage.rb' + +# Offense count: 3 +# Cop supports --auto-correct. +# Configuration parameters: EnforcedStyle, EnforcedStyleForEmptyBraces. +# SupportedStyles: space, no_space, compact +# SupportedStylesForEmptyBraces: space, no_space +Layout/SpaceInsideHashLiteralBraces: + Exclude: + - 'app/controllers/api/v1/users_controller.rb' + +# Offense count: 2 +# Cop supports --auto-correct. +# Configuration parameters: EnforcedStyle. +# SupportedStyles: final_newline, final_blank_line +Layout/TrailingEmptyLines: + Exclude: + - 'app/controllers/api/v1/users_controller.rb' + - 'config/initializers/truemail.rb' + +# Offense count: 1 +# Cop supports --auto-correct. +Lint/DeprecatedClassMethods: + Exclude: + - 'app/models/email.rb' + +# Offense count: 1 +Lint/IneffectiveAccessModifier: + Exclude: + - 'app/models/email.rb' + +# Offense count: 1 +# Cop supports --auto-correct. +Lint/RedundantStringCoercion: + Exclude: + - 'app/workers/export_worker.rb' + +# Offense count: 1 +# Cop supports --auto-correct. +# Configuration parameters: AllowUnusedKeywordArguments, IgnoreEmptyMethods, IgnoreNotImplementedMethods. +Lint/UnusedMethodArgument: + Exclude: + - 'app/models/email.rb' + +# Offense count: 1 +# Cop supports --auto-correct. +# Configuration parameters: ContextCreatingMethods, MethodCreatingMethods. +Lint/UselessAccessModifier: + Exclude: + - 'app/models/email.rb' + +# Offense count: 1 +# Configuration parameters: IgnoredMethods, CountRepeatedAttributes. +Metrics/AbcSize: + Max: 34 + +# Offense count: 1 +# Configuration parameters: CountComments, CountAsOne, ExcludedMethods, IgnoredMethods. +# IgnoredMethods: refine +Metrics/BlockLength: + Max: 47 + +# Offense count: 1 +# Configuration parameters: IgnoredMethods. +Metrics/CyclomaticComplexity: + Max: 9 + +# Offense count: 6 +# Configuration parameters: CountComments, CountAsOne, ExcludedMethods, IgnoredMethods. +Metrics/MethodLength: + Max: 22 + +# Offense count: 1 +# Configuration parameters: IgnoredMethods. +Metrics/PerceivedComplexity: + Max: 9 + +# Offense count: 8 +# Cop supports --auto-correct. +# Configuration parameters: EnforcedStyle. +# SupportedStyles: nested, compact +Style/ClassAndModuleChildren: + Exclude: + - 'app/controllers/api/v1/emails_controller.rb' + - 'app/controllers/api/v1/uploads_controller.rb' + - 'app/controllers/api/v1/users_controller.rb' + - 'test/channels/application_cable/connection_test.rb' + - 'test/controllers/api/v1/emails_controller_test.rb' + - 'test/controllers/api/v1/uploads_controller_test.rb' + - 'test/controllers/api/v1/users_controller_test.rb' + - 'test/test_helper.rb' + +# Offense count: 17 +Style/Documentation: + Enabled: false + +# Offense count: 2 +# Cop supports --auto-correct. +# Configuration parameters: EnforcedStyle. +# SupportedStyles: compact, expanded +Style/EmptyMethod: + Exclude: + - 'app/controllers/api/v1/uploads_controller.rb' + - 'app/controllers/home_controller.rb' + +# Offense count: 3 +# Cop supports --auto-correct. +Style/ExpandPathArguments: + Exclude: + - 'bin/bundle' + - 'bin/rails' + - 'bin/rake' + +# Offense count: 67 +# Cop supports --auto-correct. +# Configuration parameters: EnforcedStyle. +# SupportedStyles: always, always_true, never +Style/FrozenStringLiteralComment: + Enabled: false + +# Offense count: 1 +# Cop supports --auto-correct. +Style/GlobalStdStream: + Exclude: + - 'config/environments/production.rb' + +# Offense count: 3 +# Cop supports --auto-correct. +Style/IfUnlessModifier: + Exclude: + - 'app/models/email.rb' + - 'bin/bundle' + +# Offense count: 2 +# Cop supports --auto-correct. +# Configuration parameters: EnforcedStyle. +# SupportedStyles: both, prefix, postfix +Style/NegatedIf: + Exclude: + - 'app/models/email.rb' + +# Offense count: 1 +# Cop supports --auto-correct. +# Configuration parameters: MinDigits, Strict. +Style/NumericLiterals: + Exclude: + - 'db/schema.rb' + +# Offense count: 1 +# Cop supports --auto-correct. +Style/PerlBackrefs: + Exclude: + - 'bin/bundle' + +# Offense count: 1 +# Cop supports --auto-correct. +Style/RedundantBegin: + Exclude: + - 'bin/yarn' + +# Offense count: 1 +# Cop supports --auto-correct. +Style/RedundantConditional: + Exclude: + - 'app/models/user.rb' + +# Offense count: 2 +# Cop supports --auto-correct. +# Configuration parameters: SafeForConstants. +Style/RedundantFetchBlock: + Exclude: + - 'config/puma.rb' + +# Offense count: 1 +# Cop supports --auto-correct. +Style/RedundantRegexpEscape: + Exclude: + - 'config/initializers/truemail.rb' + +# Offense count: 4 +# Cop supports --auto-correct. +# Configuration parameters: AllowMultipleReturnValues. +Style/RedundantReturn: + Exclude: + - 'app/models/email.rb' + +# Offense count: 1 +# Cop supports --auto-correct. +Style/RedundantSelf: + Exclude: + - 'app/models/user.rb' + +# Offense count: 1 +# Cop supports --auto-correct. +# Configuration parameters: AllowModifier. +Style/SoleNestedConditional: + Exclude: + - 'app/models/email.rb' + +# Offense count: 1 +# Cop supports --auto-correct. +# Configuration parameters: . +# SupportedStyles: use_perl_names, use_english_names +Style/SpecialGlobalVars: + EnforcedStyle: use_perl_names + +# Offense count: 2 +# Cop supports --auto-correct. +Style/StderrPuts: + Exclude: + - 'bin/yarn' + +# Offense count: 282 +# Cop supports --auto-correct. +# Configuration parameters: EnforcedStyle, ConsistentQuotesInMultiline. +# SupportedStyles: single_quotes, double_quotes +Style/StringLiterals: + Enabled: false + +# Offense count: 6 +# Cop supports --auto-correct. +# Configuration parameters: MinSize. +# SupportedStyles: percent, brackets +Style/SymbolArray: + EnforcedStyle: brackets + +# Offense count: 1 +# Cop supports --auto-correct. +# Configuration parameters: IgnoredMethods. +# IgnoredMethods: respond_to, define_method +Style/SymbolProc: + Exclude: + - 'app/models/email.rb' + +# Offense count: 2 +# Cop supports --auto-correct. +# Configuration parameters: EnforcedStyleForMultiline. +# SupportedStylesForMultiline: comma, consistent_comma, no_comma +Style/TrailingCommaInHashLiteral: + Exclude: + - 'app/workers/export_worker.rb' + - 'config/environments/development.rb' + +# Offense count: 1 +# Cop supports --auto-correct. +# Configuration parameters: MinSize, WordRegex. +# SupportedStyles: percent, brackets +Style/WordArray: + EnforcedStyle: brackets + +# Offense count: 11 +# Cop supports --auto-correct. +# Configuration parameters: AutoCorrect, AllowHeredoc, AllowURI, URISchemes, IgnoreCopDirectives, IgnoredPatterns. +# URISchemes: http, https +Layout/LineLength: + Max: 198 diff --git a/app/controllers/api/v1/emails_controller.rb b/app/controllers/api/v1/emails_controller.rb index f2e37ef..5dd9795 100644 --- a/app/controllers/api/v1/emails_controller.rb +++ b/app/controllers/api/v1/emails_controller.rb @@ -1,11 +1,14 @@ class Api::V1::EmailsController < ApplicationController + before_action :require_login def index - user = User.find(params[:userid]) - emails = user.emails - render json: emails + emails = @logged_in_user.emails end def create - render json: Email.validate_email(params[:email], params[:userid]) + render json: Email.validate_email(params[:email], @logged_in_user.id) + end + + def require_login + render json: { message: "Please Login First!" }, status: :unauthorized unless !!session_user end end diff --git a/app/controllers/api/v1/uploads_controller.rb b/app/controllers/api/v1/uploads_controller.rb index 434c4d7..ac352d1 100644 --- a/app/controllers/api/v1/uploads_controller.rb +++ b/app/controllers/api/v1/uploads_controller.rb @@ -1,17 +1,22 @@ class Api::V1::UploadsController < ApplicationController def index + user = User.find(params[:userid]) + attachments = user.attachments + render json: attachments.map { |attachment| + attachment.as_json.merge({ file_name: attachment.csv_file.filename.to_s }) + } end def create original_file = params[:csv_file] file_type = original_file.content_type if file_type == "text/csv" - user_id = params[:userid] + user_id = @logged_in_user.id attachment = Attachment.create(user_id: user_id, csv_file: original_file, processed: false) ExportWorker.perform_async(attachment.id) - render json: { error: false, message: "File is processing" } + render json: { error: false, message: "Processing Your File.." } else - render json: { error: true, message: "File format not supported. Please upload CSV file." }, status: :not_acceptable + render json: { error: true, message: "File format not supported. Please upload CSV file!" }, status: :not_acceptable end end end diff --git a/app/controllers/application_controller.rb b/app/controllers/application_controller.rb index d7e0113..30ef5fd 100644 --- a/app/controllers/application_controller.rb +++ b/app/controllers/application_controller.rb @@ -1,5 +1,5 @@ class ApplicationController < ActionController::Base - def encode_token(payload) - JWT.encode(payload, "my_secret") - end + include EncodedTokenConcern + include SessionUserConcern + include DecodedTokenConcern end diff --git a/app/controllers/concerns/decoded_token_concern.rb b/app/controllers/concerns/decoded_token_concern.rb new file mode 100644 index 0000000..96f6433 --- /dev/null +++ b/app/controllers/concerns/decoded_token_concern.rb @@ -0,0 +1,11 @@ +module DecodedTokenConcern + extend ActiveSupport::Concern + def decoded_token + token = request.headers['Authorization'] + begin + JWT.decode(token, 'my_secret', false, algorithm: 'HS256') + rescue JWT::DecodeError + [] + end + end +end diff --git a/app/controllers/concerns/encoded_token_concern.rb b/app/controllers/concerns/encoded_token_concern.rb new file mode 100644 index 0000000..2876768 --- /dev/null +++ b/app/controllers/concerns/encoded_token_concern.rb @@ -0,0 +1,6 @@ +module EncodedTokenConcern + extend ActiveSupport::Concern + def encode_token(payload) + JWT.encode(payload, "my_secret") + end +end diff --git a/app/controllers/concerns/session_user_concern.rb b/app/controllers/concerns/session_user_concern.rb new file mode 100644 index 0000000..6a676a1 --- /dev/null +++ b/app/controllers/concerns/session_user_concern.rb @@ -0,0 +1,10 @@ +module SessionUserConcern + extend ActiveSupport::Concern + def session_user + decoded_hash = decoded_token + unless decoded_hash.empty? + user_id = decoded_hash[0]["user_id"] + @logged_in_user = User.find_by(id: user_id) + end + end +end diff --git a/app/javascript/components/email/Email.jsx b/app/javascript/components/email/Email.jsx index 42fc695..4f91597 100644 --- a/app/javascript/components/email/Email.jsx +++ b/app/javascript/components/email/Email.jsx @@ -2,6 +2,7 @@ import React, { useEffect } from "react"; import EmailCreate from "./EmailCreate"; import EmailList from "./EmailList"; import EmailBulk from "./EmailBulk"; +import EmailBulkList from "./EmailBulkList"; const Email = () => { return ( @@ -16,6 +17,13 @@ const Email = () => { className="d-block w-100" src="/header_main-page.svg" > + + +
+
+ +
+
diff --git a/app/javascript/components/email/EmailBulk.jsx b/app/javascript/components/email/EmailBulk.jsx index 4dd0201..d399d3a 100644 --- a/app/javascript/components/email/EmailBulk.jsx +++ b/app/javascript/components/email/EmailBulk.jsx @@ -46,6 +46,7 @@ class EmailBulk extends Component { this.setState({ isUploading: true, isError: false }); this.validateFile().then((response) => { if (response) { + const jwtToken = localStorage.getItem("jwt") const user = JSON.parse(localStorage.getItem("user")); const data = new FormData(); data.append("csv_file", this.state.file); @@ -57,6 +58,7 @@ class EmailBulk extends Component { method: "POST", headers: { "X-CSRF-Token": token, + Authorization: jwtToken, }, body: data, }).then((result) => { @@ -106,6 +108,13 @@ class EmailBulk extends Component { return result; } + downloadhandleclick = () => { + this.setState({ + isUploading: false, + isUploadSuccess: false, + }); + } + render() { return (
@@ -184,6 +193,7 @@ class EmailBulk extends Component { )} {this.state.isUploadSuccess && ( { + if (result.ok) { + result.json().then((response) => { + this.props.fetchAttachmentSuccess(response); + }); + } + }) + .catch((error) => { + console.log(error); + }); + } + + render() { + const attachments = this.props.attachments; + const allAttachments = attachments.map((attachment, index) => ( + + {index + 1} + {attachment.file_name} + + + + + + {new Date(attachment.created_at).toDateString()} + + )); + return ( +
+

+ Your's Validated CSV List +

+ {attachments.length ? ( +
+
+ + + + + + + + + + {allAttachments} +
#FileDownloadAdded
+
+
+ ) : ( +
+ Email List is empty. Why not upload one? +
+ )} +
+ ); + } +} + +const mapStateToProps = (state) => { + return { + attachments: state.attachment.attachments, + }; +}; + +const mapDispatchToProps = (dispatch) => { + return { + fetchAttachmentSuccess: (payload) => + dispatch(fetchAttachmentSuccess(payload)), + }; +}; + +export default connect(mapStateToProps, mapDispatchToProps)(EmailBulkList); + +export { EmailBulkList }; \ No newline at end of file diff --git a/app/javascript/components/email/EmailList.jsx b/app/javascript/components/email/EmailList.jsx index 9f9be3d..0a10179 100644 --- a/app/javascript/components/email/EmailList.jsx +++ b/app/javascript/components/email/EmailList.jsx @@ -9,8 +9,13 @@ class EmailList extends Component { componentDidMount() { const user = JSON.parse(localStorage.getItem("user")); - const url = `/api/v1/emails?userid=${user.id}`; - fetch(url) + const token = localStorage.getItem("jwt"); + const url = `/api/v1/emails`; + fetch(url, { + headers: { + Authorization:token + } + }) .then((result) => { if (result.ok) { result.json().then((response) => { @@ -25,7 +30,7 @@ class EmailList extends Component { render() { const emails = this.props.emails; - const allEmails = emails.slice(0, 20).map((emailEle, index) => ( + const allEmails = emails.map((emailEle, index) => (
  • {emailEle.email}
  • diff --git a/app/javascript/components/layout/Footer.jsx b/app/javascript/components/layout/Footer.jsx index 7a24242..d6ff43d 100644 --- a/app/javascript/components/layout/Footer.jsx +++ b/app/javascript/components/layout/Footer.jsx @@ -2,7 +2,7 @@ import React from "react"; import "font-awesome/css/font-awesome.min.css"; export default () => ( -
    +
    diff --git a/app/javascript/components/layout/Header.jsx b/app/javascript/components/layout/Header.jsx index e0ac834..2804812 100644 --- a/app/javascript/components/layout/Header.jsx +++ b/app/javascript/components/layout/Header.jsx @@ -3,7 +3,7 @@ import { Link } from "react-router-dom"; import Navbar from "./Navbar"; export default () => ( -