activestorage 7.0.0 → 7.0.2.2

Sign up to get free protection for your applications and to get access to all the features.

Potentially problematic release.


This version of activestorage might be problematic. Click here for more details.

checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 85a5cf62726ae4b98295bb1b62926f4f2fa15257babdb8d6251cff37c682c354
4
- data.tar.gz: 65f662b546c7f3e5eaf0775f065174f6d7162721578d763213eefd2875565a7b
3
+ metadata.gz: 797efdf2ca8b6bb58815e2352e430b2cca2b6defaf37fc4e524c2a2150695f4a
4
+ data.tar.gz: 11490b758f9b6e9c2a9eda88757e5a454ca92e587624ce85cb6235dfa9f10fbd
5
5
  SHA512:
6
- metadata.gz: 3ff136a959f672bb822be34f573209a3017744a8ba476e8f6e2ec3de11130b9fb1bf4e876ee2b0233b1a2bfa9acd66d211b2b9b329f533b9449fd8d084482ec6
7
- data.tar.gz: 1d38c4402a276a86847c492c1d373fab6ace21b6149e03426744561a1528307947f4353645b53db5bdf32cfa4776aa0c15cfd0591631bdc554be66b481f5d77e
6
+ metadata.gz: 02a012dd3e41df712e0b4f64576db45634659b369d5e09245c6cc87e1bbb38d31bebd2e110d5782f97477ba2798717f9770167325c68b3b3b8c12d3409c492c5
7
+ data.tar.gz: b89aa21d7d77e5c4ed766c507b06c7c81b34cf79db5fd01f8f1aaa171476e88cf90cabb0e576ebfba698065ab1daee2021cb34b6a9ba2da7054a21907fcd0218
data/CHANGELOG.md CHANGED
@@ -1,3 +1,33 @@
1
+ ## Rails 7.0.2.2 (February 11, 2022) ##
2
+
3
+ * No changes.
4
+
5
+
6
+ ## Rails 7.0.2.1 (February 11, 2022) ##
7
+
8
+ * No changes.
9
+
10
+
11
+ ## Rails 7.0.2 (February 08, 2022) ##
12
+
13
+ * Revert the ability to pass `service_name` param to `DirectUploadsController` which was introduced
14
+ in 7.0.0.
15
+
16
+ That change caused a lot of problems to upgrade Rails applications so we decided to remove it
17
+ while in work in a more backwards compatible implementation.
18
+
19
+ *Gannon McGibbon*
20
+
21
+ * Allow applications to opt out of precompiling Active Storage JavaScript assets.
22
+
23
+ *jlestavel*
24
+
25
+
26
+ ## Rails 7.0.1 (January 06, 2022) ##
27
+
28
+ * No changes.
29
+
30
+
1
31
  ## Rails 7.0.0 (December 15, 2021) ##
2
32
 
3
33
  * Support transforming empty-ish `has_many_attached` value into `[]` (e.g. `[""]`).
data/MIT-LICENSE CHANGED
@@ -1,4 +1,4 @@
1
- Copyright (c) 2017-2021 David Heinemeier Hansson, Basecamp
1
+ Copyright (c) 2017-2022 David Heinemeier Hansson, Basecamp
2
2
 
3
3
  Permission is hereby granted, free of charge, to any person obtaining
4
4
  a copy of this software and associated documentation files (the
@@ -508,7 +508,7 @@ function toArray(value) {
508
508
  }
509
509
 
510
510
  class BlobRecord {
511
- constructor(file, checksum, url, directUploadToken, attachmentName) {
511
+ constructor(file, checksum, url) {
512
512
  this.file = file;
513
513
  this.attributes = {
514
514
  filename: file.name,
@@ -516,8 +516,6 @@ class BlobRecord {
516
516
  byte_size: file.size,
517
517
  checksum: checksum
518
518
  };
519
- this.directUploadToken = directUploadToken;
520
- this.attachmentName = attachmentName;
521
519
  this.xhr = new XMLHttpRequest;
522
520
  this.xhr.open("POST", url, true);
523
521
  this.xhr.responseType = "json";
@@ -545,9 +543,7 @@ class BlobRecord {
545
543
  create(callback) {
546
544
  this.callback = callback;
547
545
  this.xhr.send(JSON.stringify({
548
- blob: this.attributes,
549
- direct_upload_token: this.directUploadToken,
550
- attachment_name: this.attachmentName
546
+ blob: this.attributes
551
547
  }));
552
548
  }
553
549
  requestDidLoad(event) {
@@ -608,12 +604,10 @@ class BlobUpload {
608
604
  let id = 0;
609
605
 
610
606
  class DirectUpload {
611
- constructor(file, url, serviceName, attachmentName, delegate) {
607
+ constructor(file, url, delegate) {
612
608
  this.id = ++id;
613
609
  this.file = file;
614
610
  this.url = url;
615
- this.serviceName = serviceName;
616
- this.attachmentName = attachmentName;
617
611
  this.delegate = delegate;
618
612
  }
619
613
  create(callback) {
@@ -622,7 +616,7 @@ class DirectUpload {
622
616
  callback(error);
623
617
  return;
624
618
  }
625
- const blob = new BlobRecord(this.file, checksum, this.url, this.serviceName, this.attachmentName);
619
+ const blob = new BlobRecord(this.file, checksum, this.url);
626
620
  notify(this.delegate, "directUploadWillCreateBlobWithXHR", blob.xhr);
627
621
  blob.create((error => {
628
622
  if (error) {
@@ -653,7 +647,7 @@ class DirectUploadController {
653
647
  constructor(input, file) {
654
648
  this.input = input;
655
649
  this.file = file;
656
- this.directUpload = new DirectUpload(this.file, this.url, this.directUploadToken, this.attachmentName, this);
650
+ this.directUpload = new DirectUpload(this.file, this.url, this);
657
651
  this.dispatch("initialize");
658
652
  }
659
653
  start(callback) {
@@ -684,12 +678,6 @@ class DirectUploadController {
684
678
  get url() {
685
679
  return this.input.getAttribute("data-direct-upload-url");
686
680
  }
687
- get directUploadToken() {
688
- return this.input.getAttribute("data-direct-upload-token");
689
- }
690
- get attachmentName() {
691
- return this.input.getAttribute("data-direct-upload-attachment-name");
692
- }
693
681
  dispatch(name, detail = {}) {
694
682
  detail.file = this.file;
695
683
  detail.id = this.directUpload.id;
@@ -503,7 +503,7 @@
503
503
  }
504
504
  }
505
505
  class BlobRecord {
506
- constructor(file, checksum, url, directUploadToken, attachmentName) {
506
+ constructor(file, checksum, url) {
507
507
  this.file = file;
508
508
  this.attributes = {
509
509
  filename: file.name,
@@ -511,8 +511,6 @@
511
511
  byte_size: file.size,
512
512
  checksum: checksum
513
513
  };
514
- this.directUploadToken = directUploadToken;
515
- this.attachmentName = attachmentName;
516
514
  this.xhr = new XMLHttpRequest;
517
515
  this.xhr.open("POST", url, true);
518
516
  this.xhr.responseType = "json";
@@ -540,9 +538,7 @@
540
538
  create(callback) {
541
539
  this.callback = callback;
542
540
  this.xhr.send(JSON.stringify({
543
- blob: this.attributes,
544
- direct_upload_token: this.directUploadToken,
545
- attachment_name: this.attachmentName
541
+ blob: this.attributes
546
542
  }));
547
543
  }
548
544
  requestDidLoad(event) {
@@ -600,12 +596,10 @@
600
596
  }
601
597
  let id = 0;
602
598
  class DirectUpload {
603
- constructor(file, url, serviceName, attachmentName, delegate) {
599
+ constructor(file, url, delegate) {
604
600
  this.id = ++id;
605
601
  this.file = file;
606
602
  this.url = url;
607
- this.serviceName = serviceName;
608
- this.attachmentName = attachmentName;
609
603
  this.delegate = delegate;
610
604
  }
611
605
  create(callback) {
@@ -614,7 +608,7 @@
614
608
  callback(error);
615
609
  return;
616
610
  }
617
- const blob = new BlobRecord(this.file, checksum, this.url, this.serviceName, this.attachmentName);
611
+ const blob = new BlobRecord(this.file, checksum, this.url);
618
612
  notify(this.delegate, "directUploadWillCreateBlobWithXHR", blob.xhr);
619
613
  blob.create((error => {
620
614
  if (error) {
@@ -643,7 +637,7 @@
643
637
  constructor(input, file) {
644
638
  this.input = input;
645
639
  this.file = file;
646
- this.directUpload = new DirectUpload(this.file, this.url, this.directUploadToken, this.attachmentName, this);
640
+ this.directUpload = new DirectUpload(this.file, this.url, this);
647
641
  this.dispatch("initialize");
648
642
  }
649
643
  start(callback) {
@@ -674,12 +668,6 @@
674
668
  get url() {
675
669
  return this.input.getAttribute("data-direct-upload-url");
676
670
  }
677
- get directUploadToken() {
678
- return this.input.getAttribute("data-direct-upload-token");
679
- }
680
- get attachmentName() {
681
- return this.input.getAttribute("data-direct-upload-attachment-name");
682
- }
683
671
  dispatch(name, detail = {}) {
684
672
  detail.file = this.file;
685
673
  detail.id = this.directUpload.id;
@@ -4,10 +4,8 @@
4
4
  # When the client-side upload is completed, the signed_blob_id can be submitted as part of the form to reference
5
5
  # the blob that was created up front.
6
6
  class ActiveStorage::DirectUploadsController < ActiveStorage::BaseController
7
- include ActiveStorage::DirectUploadToken
8
-
9
7
  def create
10
- blob = ActiveStorage::Blob.create_before_direct_upload!(**blob_args.merge(service_name: verified_service_name))
8
+ blob = ActiveStorage::Blob.create_before_direct_upload!(**blob_args)
11
9
  render json: direct_upload_json(blob)
12
10
  end
13
11
 
@@ -16,10 +14,6 @@ class ActiveStorage::DirectUploadsController < ActiveStorage::BaseController
16
14
  params.require(:blob).permit(:filename, :byte_size, :checksum, :content_type, metadata: {}).to_h.symbolize_keys
17
15
  end
18
16
 
19
- def verified_service_name
20
- ActiveStorage::DirectUploadToken.verify_direct_upload_token(params[:direct_upload_token], params[:attachment_name], session)
21
- end
22
-
23
17
  def direct_upload_json(blob)
24
18
  blob.as_json(root: false, methods: :signed_id).merge(direct_upload: {
25
19
  url: blob.service_url_for_direct_upload,
@@ -1,19 +1,16 @@
1
1
  import { getMetaValue } from "./helpers"
2
2
 
3
3
  export class BlobRecord {
4
- constructor(file, checksum, url, directUploadToken, attachmentName) {
4
+ constructor(file, checksum, url) {
5
5
  this.file = file
6
6
 
7
7
  this.attributes = {
8
8
  filename: file.name,
9
9
  content_type: file.type || "application/octet-stream",
10
10
  byte_size: file.size,
11
- checksum: checksum,
11
+ checksum: checksum
12
12
  }
13
13
 
14
- this.directUploadToken = directUploadToken
15
- this.attachmentName = attachmentName
16
-
17
14
  this.xhr = new XMLHttpRequest
18
15
  this.xhr.open("POST", url, true)
19
16
  this.xhr.responseType = "json"
@@ -46,11 +43,7 @@ export class BlobRecord {
46
43
 
47
44
  create(callback) {
48
45
  this.callback = callback
49
- this.xhr.send(JSON.stringify({
50
- blob: this.attributes,
51
- direct_upload_token: this.directUploadToken,
52
- attachment_name: this.attachmentName
53
- }))
46
+ this.xhr.send(JSON.stringify({ blob: this.attributes }))
54
47
  }
55
48
 
56
49
  requestDidLoad(event) {
@@ -5,12 +5,10 @@ import { BlobUpload } from "./blob_upload"
5
5
  let id = 0
6
6
 
7
7
  export class DirectUpload {
8
- constructor(file, url, serviceName, attachmentName, delegate) {
8
+ constructor(file, url, delegate) {
9
9
  this.id = ++id
10
10
  this.file = file
11
11
  this.url = url
12
- this.serviceName = serviceName
13
- this.attachmentName = attachmentName
14
12
  this.delegate = delegate
15
13
  }
16
14
 
@@ -21,7 +19,7 @@ export class DirectUpload {
21
19
  return
22
20
  }
23
21
 
24
- const blob = new BlobRecord(this.file, checksum, this.url, this.serviceName, this.attachmentName)
22
+ const blob = new BlobRecord(this.file, checksum, this.url)
25
23
  notify(this.delegate, "directUploadWillCreateBlobWithXHR", blob.xhr)
26
24
 
27
25
  blob.create(error => {
@@ -5,7 +5,7 @@ export class DirectUploadController {
5
5
  constructor(input, file) {
6
6
  this.input = input
7
7
  this.file = file
8
- this.directUpload = new DirectUpload(this.file, this.url, this.directUploadToken, this.attachmentName, this)
8
+ this.directUpload = new DirectUpload(this.file, this.url, this)
9
9
  this.dispatch("initialize")
10
10
  }
11
11
 
@@ -41,14 +41,6 @@ export class DirectUploadController {
41
41
  return this.input.getAttribute("data-direct-upload-url")
42
42
  }
43
43
 
44
- get directUploadToken() {
45
- return this.input.getAttribute("data-direct-upload-token")
46
- }
47
-
48
- get attachmentName() {
49
- return this.input.getAttribute("data-direct-upload-attachment-name")
50
- }
51
-
52
44
  dispatch(name, detail = {}) {
53
45
  detail.file = this.file
54
46
  detail.id = this.directUpload.id
@@ -4,7 +4,7 @@
4
4
  # These variants are used to create thumbnails, fixed-size avatars, or any other derivative image from the
5
5
  # original.
6
6
  #
7
- # Variants rely on {ImageProcessing}[https://github.com/janko-m/image_processing] gem for the actual transformations
7
+ # Variants rely on {ImageProcessing}[https://github.com/janko/image_processing] gem for the actual transformations
8
8
  # of the file, so you must add <tt>gem "image_processing"</tt> to your Gemfile if you wish to use variants. By
9
9
  # default, images will be processed with {ImageMagick}[http://imagemagick.org] using the
10
10
  # {MiniMagick}[https://github.com/minimagick/minimagick] gem, but you can also switch to the
@@ -46,9 +46,9 @@
46
46
  #
47
47
  # Visit the following links for a list of available ImageProcessing commands and ImageMagick/libvips operations:
48
48
  #
49
- # * {ImageProcessing::MiniMagick}[https://github.com/janko-m/image_processing/blob/master/doc/minimagick.md#methods]
49
+ # * {ImageProcessing::MiniMagick}[https://github.com/janko/image_processing/blob/master/doc/minimagick.md#methods]
50
50
  # * {ImageMagick reference}[https://www.imagemagick.org/script/mogrify.php]
51
- # * {ImageProcessing::Vips}[https://github.com/janko-m/image_processing/blob/master/doc/vips.md#methods]
51
+ # * {ImageProcessing::Vips}[https://github.com/janko/image_processing/blob/master/doc/vips.md#methods]
52
52
  # * {ruby-vips reference}[http://www.rubydoc.info/gems/ruby-vips/Vips/Image]
53
53
  class ActiveStorage::Variant
54
54
  attr_reader :blob, :variation
@@ -10,7 +10,7 @@ require "mini_mime"
10
10
  #
11
11
  # ActiveStorage::Variation.new(resize_to_limit: [100, 100], colourspace: "b-w", rotate: "-90", saver: { trim: true })
12
12
  #
13
- # The options map directly to {ImageProcessing}[https://github.com/janko-m/image_processing] commands.
13
+ # The options map directly to {ImageProcessing}[https://github.com/janko/image_processing] commands.
14
14
  class ActiveStorage::Variation
15
15
  attr_reader :transformations
16
16
 
@@ -54,7 +54,7 @@ module ActiveStorage
54
54
  end
55
55
  end
56
56
  rescue Errno::ENOENT
57
- logger.info "Skipping audio analysis because FFmpeg isn't installed"
57
+ logger.info "Skipping audio analysis because ffprobe isn't installed"
58
58
  {}
59
59
  end
60
60
 
@@ -133,7 +133,7 @@ module ActiveStorage
133
133
  end
134
134
  end
135
135
  rescue Errno::ENOENT
136
- logger.info "Skipping video analysis because FFmpeg isn't installed"
136
+ logger.info "Skipping video analysis because ffprobe isn't installed"
137
137
  {}
138
138
  end
139
139
 
@@ -30,6 +30,7 @@ module ActiveStorage
30
30
  config.active_storage.analyzers = [ ActiveStorage::Analyzer::ImageAnalyzer::Vips, ActiveStorage::Analyzer::ImageAnalyzer::ImageMagick, ActiveStorage::Analyzer::VideoAnalyzer, ActiveStorage::Analyzer::AudioAnalyzer ]
31
31
  config.active_storage.paths = ActiveSupport::OrderedOptions.new
32
32
  config.active_storage.queues = ActiveSupport::InheritableOptions.new
33
+ config.active_storage.precompile_assets = true
33
34
 
34
35
  config.active_storage.variable_content_types = %w(
35
36
  image/png
@@ -167,8 +168,10 @@ module ActiveStorage
167
168
  end
168
169
 
169
170
  initializer "active_storage.asset" do
170
- if Rails.application.config.respond_to?(:assets)
171
- Rails.application.config.assets.precompile += %w( activestorage activestorage.esm )
171
+ config.after_initialize do |app|
172
+ if app.config.respond_to?(:assets) && app.config.active_storage.precompile_assets
173
+ app.config.assets.precompile += %w( activestorage activestorage.esm )
174
+ end
172
175
  end
173
176
  end
174
177
 
@@ -26,7 +26,4 @@ module ActiveStorage
26
26
 
27
27
  # Raised when a Previewer is unable to generate a preview image.
28
28
  class PreviewError < Error; end
29
-
30
- # Raised when direct upload fails because of the invalid token
31
- class InvalidDirectUploadTokenError < Error; end
32
29
  end
@@ -9,8 +9,8 @@ module ActiveStorage
9
9
  module VERSION
10
10
  MAJOR = 7
11
11
  MINOR = 0
12
- TINY = 0
13
- PRE = nil
12
+ TINY = 2
13
+ PRE = "2"
14
14
 
15
15
  STRING = [MAJOR, MINOR, TINY, PRE].compact.join(".")
16
16
  end
@@ -1,5 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
+ require "shellwords"
4
+
3
5
  module ActiveStorage
4
6
  class Previewer::VideoPreviewer < Previewer
5
7
  class << self
@@ -1,7 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  #--
4
- # Copyright (c) 2017-2021 David Heinemeier Hansson, Basecamp
4
+ # Copyright (c) 2017-2022 David Heinemeier Hansson, Basecamp
5
5
  #
6
6
  # Permission is hereby granted, free of charge, to any person obtaining
7
7
  # a copy of this software and associated documentation files (the
@@ -41,7 +41,6 @@ module ActiveStorage
41
41
  autoload :Service
42
42
  autoload :Previewer
43
43
  autoload :Analyzer
44
- autoload :DirectUploadToken
45
44
 
46
45
  mattr_accessor :logger
47
46
  mattr_accessor :verifier
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: activestorage
3
3
  version: !ruby/object:Gem::Version
4
- version: 7.0.0
4
+ version: 7.0.2.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - David Heinemeier Hansson
8
- autorequire:
8
+ autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2021-12-15 00:00:00.000000000 Z
11
+ date: 2022-02-11 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: activesupport
@@ -16,56 +16,56 @@ dependencies:
16
16
  requirements:
17
17
  - - '='
18
18
  - !ruby/object:Gem::Version
19
- version: 7.0.0
19
+ version: 7.0.2.2
20
20
  type: :runtime
21
21
  prerelease: false
22
22
  version_requirements: !ruby/object:Gem::Requirement
23
23
  requirements:
24
24
  - - '='
25
25
  - !ruby/object:Gem::Version
26
- version: 7.0.0
26
+ version: 7.0.2.2
27
27
  - !ruby/object:Gem::Dependency
28
28
  name: actionpack
29
29
  requirement: !ruby/object:Gem::Requirement
30
30
  requirements:
31
31
  - - '='
32
32
  - !ruby/object:Gem::Version
33
- version: 7.0.0
33
+ version: 7.0.2.2
34
34
  type: :runtime
35
35
  prerelease: false
36
36
  version_requirements: !ruby/object:Gem::Requirement
37
37
  requirements:
38
38
  - - '='
39
39
  - !ruby/object:Gem::Version
40
- version: 7.0.0
40
+ version: 7.0.2.2
41
41
  - !ruby/object:Gem::Dependency
42
42
  name: activejob
43
43
  requirement: !ruby/object:Gem::Requirement
44
44
  requirements:
45
45
  - - '='
46
46
  - !ruby/object:Gem::Version
47
- version: 7.0.0
47
+ version: 7.0.2.2
48
48
  type: :runtime
49
49
  prerelease: false
50
50
  version_requirements: !ruby/object:Gem::Requirement
51
51
  requirements:
52
52
  - - '='
53
53
  - !ruby/object:Gem::Version
54
- version: 7.0.0
54
+ version: 7.0.2.2
55
55
  - !ruby/object:Gem::Dependency
56
56
  name: activerecord
57
57
  requirement: !ruby/object:Gem::Requirement
58
58
  requirements:
59
59
  - - '='
60
60
  - !ruby/object:Gem::Version
61
- version: 7.0.0
61
+ version: 7.0.2.2
62
62
  type: :runtime
63
63
  prerelease: false
64
64
  version_requirements: !ruby/object:Gem::Requirement
65
65
  requirements:
66
66
  - - '='
67
67
  - !ruby/object:Gem::Version
68
- version: 7.0.0
68
+ version: 7.0.2.2
69
69
  - !ruby/object:Gem::Dependency
70
70
  name: marcel
71
71
  requirement: !ruby/object:Gem::Requirement
@@ -170,7 +170,6 @@ files:
170
170
  - lib/active_storage/attached/many.rb
171
171
  - lib/active_storage/attached/model.rb
172
172
  - lib/active_storage/attached/one.rb
173
- - lib/active_storage/direct_upload_token.rb
174
173
  - lib/active_storage/downloader.rb
175
174
  - lib/active_storage/engine.rb
176
175
  - lib/active_storage/errors.rb
@@ -199,12 +198,12 @@ licenses:
199
198
  - MIT
200
199
  metadata:
201
200
  bug_tracker_uri: https://github.com/rails/rails/issues
202
- changelog_uri: https://github.com/rails/rails/blob/v7.0.0/activestorage/CHANGELOG.md
203
- documentation_uri: https://api.rubyonrails.org/v7.0.0/
201
+ changelog_uri: https://github.com/rails/rails/blob/v7.0.2.2/activestorage/CHANGELOG.md
202
+ documentation_uri: https://api.rubyonrails.org/v7.0.2.2/
204
203
  mailing_list_uri: https://discuss.rubyonrails.org/c/rubyonrails-talk
205
- source_code_uri: https://github.com/rails/rails/tree/v7.0.0/activestorage
204
+ source_code_uri: https://github.com/rails/rails/tree/v7.0.2.2/activestorage
206
205
  rubygems_mfa_required: 'true'
207
- post_install_message:
206
+ post_install_message:
208
207
  rdoc_options: []
209
208
  require_paths:
210
209
  - lib
@@ -219,8 +218,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
219
218
  - !ruby/object:Gem::Version
220
219
  version: '0'
221
220
  requirements: []
222
- rubygems_version: 3.2.32
223
- signing_key:
221
+ rubygems_version: 3.2.22
222
+ signing_key:
224
223
  specification_version: 4
225
224
  summary: Local and cloud file storage framework.
226
225
  test_files: []
@@ -1,59 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module ActiveStorage
4
- module DirectUploadToken
5
- extend self
6
-
7
- SEPARATOR = "."
8
- DIRECT_UPLOAD_TOKEN_LENGTH = 32
9
-
10
- def generate_direct_upload_token(attachment_name, service_name, session)
11
- token = direct_upload_token(session, attachment_name)
12
- encode_direct_upload_token([service_name, token].join(SEPARATOR))
13
- end
14
-
15
- def verify_direct_upload_token(token, attachment_name, session)
16
- raise ActiveStorage::InvalidDirectUploadTokenError if token.nil?
17
-
18
- service_name, *token_components = decode_token(token).split(SEPARATOR)
19
- decoded_token = token_components.join(SEPARATOR)
20
-
21
- return service_name if valid_direct_upload_token?(decoded_token, attachment_name, session)
22
-
23
- raise ActiveStorage::InvalidDirectUploadTokenError
24
- end
25
-
26
- private
27
- def direct_upload_token(session, attachment_name) # :doc:
28
- direct_upload_token_hmac(session, "direct_upload##{attachment_name}")
29
- end
30
-
31
- def valid_direct_upload_token?(token, attachment_name, session) # :doc:
32
- correct_token = direct_upload_token(session, attachment_name)
33
- ActiveSupport::SecurityUtils.fixed_length_secure_compare(token, correct_token)
34
- rescue ArgumentError
35
- raise ActiveStorage::InvalidDirectUploadTokenError
36
- end
37
-
38
- def direct_upload_token_hmac(session, identifier) # :doc:
39
- OpenSSL::HMAC.digest(
40
- OpenSSL::Digest::SHA256.new,
41
- real_direct_upload_token(session),
42
- identifier
43
- )
44
- end
45
-
46
- def real_direct_upload_token(session) # :doc:
47
- session[:_direct_upload_token] ||= SecureRandom.urlsafe_base64(DIRECT_UPLOAD_TOKEN_LENGTH, padding: false)
48
- encode_direct_upload_token(session[:_direct_upload_token])
49
- end
50
-
51
- def decode_token(encoded_token) # :nodoc:
52
- Base64.urlsafe_decode64(encoded_token)
53
- end
54
-
55
- def encode_direct_upload_token(raw_token) # :nodoc:
56
- Base64.urlsafe_encode64(raw_token)
57
- end
58
- end
59
- end