darjeelink 0.11.8 → 0.13.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/README.md +56 -0
- data/app/controllers/darjeelink/api_controller.rb +64 -0
- data/app/models/darjeelink/api_token.rb +14 -0
- data/app/models/darjeelink/short_link.rb +1 -1
- data/config/brakeman.ignore +26 -0
- data/config/initializers/darjeelink.rb +9 -6
- data/config/routes.rb +1 -0
- data/db/migrate/20210610083330_create_darjeelink_api_tokens.rb +15 -0
- data/lib/darjeelink/configuration.rb +1 -5
- data/lib/darjeelink/version.rb +1 -1
- metadata +43 -11
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: ca8f37399422052422670335b4e69c6f52de45549aa93ec34311b29347aab47d
|
4
|
+
data.tar.gz: 204d687368b9708e6ef8b6f0b06318bffd7fac0ad177b7f4cdfc5b44d415b3c2
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: cd1b3cc45ccb146106aa6acd72aa625269e4730432078c1bb803b4179bf9095b2aa5fa42f3960e6570235b9a280fc318772fdade81ccd77a566a1f1dcb6550e4
|
7
|
+
data.tar.gz: 848a20765a23dde62eb9c3f937c4384917577e78af8bca65417c3ae17cc447011c021aaae9bb7eabde13e114daaa0a8522ba10270c9943a96b7d5a1ce561c4be
|
data/README.md
CHANGED
@@ -19,6 +19,48 @@ There is a UTM generator, where you can provide:
|
|
19
19
|
- a campaign identifier
|
20
20
|
And you can get a link with UTM params all filled in, and shortern it with one click.
|
21
21
|
|
22
|
+
## API
|
23
|
+
There is an API available to create short links.
|
24
|
+
To create a short link via the API:
|
25
|
+
|
26
|
+
First, create an api token `Darjeelink::ApiToken.create!(username: <username>, active: true)`.
|
27
|
+
Then grab the token.
|
28
|
+
|
29
|
+
Next, make a request
|
30
|
+
```
|
31
|
+
POST /api
|
32
|
+
Authorization => Token token=<username>:<token>
|
33
|
+
{
|
34
|
+
short_link: {
|
35
|
+
url: 'https://www.example.com',
|
36
|
+
shortened_path: 'xmpl' (optional)
|
37
|
+
}
|
38
|
+
}
|
39
|
+
```
|
40
|
+
`url` is the absolute URI that you wish to shorten
|
41
|
+
`shortened_path` is the path that you will visit to get redirected to your original link. It is optional. If it is not provided one will be generated automatically
|
42
|
+
|
43
|
+
If successful you will get a response like:
|
44
|
+
```
|
45
|
+
STATUS 201
|
46
|
+
{
|
47
|
+
short_link: <shortened_url>
|
48
|
+
}
|
49
|
+
```
|
50
|
+
|
51
|
+
If unsuccessful you will get a response like
|
52
|
+
```
|
53
|
+
STATUS 400
|
54
|
+
{
|
55
|
+
error: "information on what went wrong"
|
56
|
+
}
|
57
|
+
```
|
58
|
+
|
59
|
+
If authorization failed you will get a response like
|
60
|
+
```
|
61
|
+
STATUS 401
|
62
|
+
{}
|
63
|
+
```
|
22
64
|
## Installation
|
23
65
|
### Gemfile
|
24
66
|
Add these lines to your app's Gemfile
|
@@ -72,6 +114,20 @@ Run `cp .env.sample spec/dummy/.env.test`
|
|
72
114
|
|
73
115
|
Change the database url to be different to the development one i.e. `postgres://darjeelink_dbuser:password@localhost/darjeelink-test`
|
74
116
|
|
117
|
+
## Releasing
|
118
|
+
Darjeelink follows [Semantic Versioning](https://semver.org)
|
119
|
+
|
120
|
+
Once all necessary changes have made it in to master and you are ready to do a release you need to do these steps.
|
121
|
+
|
122
|
+
Note that if you are running in a vagrant VM, most of these steps can be done from within the VM.
|
123
|
+
|
124
|
+
- Update `lib/darjeelink/version.rb` to the new version
|
125
|
+
- Run `bundle install` to pick up the change in Gemfile.lock
|
126
|
+
- Commit the changes to `lib/darjeelink/version.rb` and `Gemfile.lock`, and push them to GitHub
|
127
|
+
- Go to `https://github.com/38degrees/darjeelink/releases` and create a release tag in GitHub
|
128
|
+
- Run `gem build darjeelink.gemspec` this will output a file `darjeelink-X.X.X.gem` the version should match what version.rb and github.
|
129
|
+
- Run `gem push darjeelink-X.X.X.gem`
|
130
|
+
|
75
131
|
## GDPR
|
76
132
|
No personally identifiable data is stored about the public by this gem.
|
77
133
|
It does not store information on individual clicks, only a counter of how many times a link has been clicked.
|
@@ -0,0 +1,64 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Darjeelink
|
4
|
+
class ApiController < Darjeelink::ApplicationController
|
5
|
+
skip_before_action :check_ip_whitelist
|
6
|
+
skip_before_action :authenticate
|
7
|
+
|
8
|
+
before_action :authenticate_token
|
9
|
+
|
10
|
+
def create
|
11
|
+
short_link = Darjeelink::ShortLink.create!(short_link_params)
|
12
|
+
|
13
|
+
render(
|
14
|
+
json: { short_link: "#{Darjeelink.domain}/#{short_link.shortened_path}" },
|
15
|
+
status: :created
|
16
|
+
)
|
17
|
+
rescue ActiveRecord::RecordNotUnique
|
18
|
+
render(
|
19
|
+
json: { error: "#{short_link_params[:shortened_path]} already used! Choose a different custom path" },
|
20
|
+
status: :bad_request
|
21
|
+
)
|
22
|
+
rescue ActiveRecord::RecordInvalid => e
|
23
|
+
render(
|
24
|
+
json: { error: e.message.to_s },
|
25
|
+
status: :bad_request
|
26
|
+
)
|
27
|
+
rescue ActionController::ParameterMissing
|
28
|
+
render(
|
29
|
+
json: { error: 'Missing required params' },
|
30
|
+
status: :bad_request
|
31
|
+
)
|
32
|
+
end
|
33
|
+
|
34
|
+
private
|
35
|
+
|
36
|
+
def short_link_params
|
37
|
+
params.require(:short_link).permit(:url, :shortened_path)
|
38
|
+
end
|
39
|
+
|
40
|
+
def authenticate_token
|
41
|
+
# The Authorization header must be supplied in the following format:
|
42
|
+
# "Authorization" => "Token token=#{username}:#{token}"
|
43
|
+
authenticate_or_request_with_http_token do |username_token, _options|
|
44
|
+
# Perform token comparison; avoid timing attacks and length leaks
|
45
|
+
# See: https://thisdata.com/blog/timing-attacks-against-string-comparison/
|
46
|
+
return head(:unauthorized) unless valid_authorization_token?(username_token)
|
47
|
+
|
48
|
+
return true
|
49
|
+
end
|
50
|
+
end
|
51
|
+
|
52
|
+
def valid_authorization_token?(username_token)
|
53
|
+
username, token = username_token.split ':'
|
54
|
+
|
55
|
+
stored_token = ApiToken.find_by(username: username, active: true)&.token
|
56
|
+
return false if stored_token.nil?
|
57
|
+
|
58
|
+
ActiveSupport::SecurityUtils.secure_compare(
|
59
|
+
token,
|
60
|
+
stored_token
|
61
|
+
)
|
62
|
+
end
|
63
|
+
end
|
64
|
+
end
|
@@ -0,0 +1,14 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Darjeelink
|
4
|
+
class ApiToken < ApplicationRecord
|
5
|
+
validates :username, uniqueness: true
|
6
|
+
validates :token, length: { minimum: 32 }, uniqueness: true
|
7
|
+
|
8
|
+
before_validation :generate_token
|
9
|
+
|
10
|
+
def generate_token
|
11
|
+
self.token = SecureRandom.uuid if token.blank?
|
12
|
+
end
|
13
|
+
end
|
14
|
+
end
|
@@ -0,0 +1,26 @@
|
|
1
|
+
{
|
2
|
+
"ignored_warnings": [
|
3
|
+
{
|
4
|
+
"warning_type": "Mass Assignment",
|
5
|
+
"warning_code": 70,
|
6
|
+
"fingerprint": "4c710243b0d9f3f174b1b0b465dcd19aca14b1f1a9658572b13a1172855b6ed7",
|
7
|
+
"check_name": "MassAssignment",
|
8
|
+
"message": "Parameters should be whitelisted for mass assignment",
|
9
|
+
"file": "app/controllers/darjeelink/short_links_controller.rb",
|
10
|
+
"line": 83,
|
11
|
+
"link": "https://brakemanscanner.org/docs/warning_types/mass_assignment/",
|
12
|
+
"code": "params.permit!",
|
13
|
+
"render_path": null,
|
14
|
+
"location": {
|
15
|
+
"type": "method",
|
16
|
+
"class": "Darjeelink::ShortLinksController",
|
17
|
+
"method": "build_url"
|
18
|
+
},
|
19
|
+
"user_input": null,
|
20
|
+
"confidence": "Medium",
|
21
|
+
"note": "The params aren't being use to create a record, we just use it to merge params that might be present on the shortened url and the source url"
|
22
|
+
}
|
23
|
+
],
|
24
|
+
"updated": "2020-07-23 16:52:33 +0000",
|
25
|
+
"brakeman_version": "4.8.2"
|
26
|
+
}
|
@@ -14,14 +14,17 @@ Darjeelink.configure do |config|
|
|
14
14
|
'sms-blast': 'SMS Blast',
|
15
15
|
'google-advert': 'Google advert',
|
16
16
|
'instagram-advert': 'Instagram Advert',
|
17
|
-
'
|
18
|
-
'
|
19
|
-
|
20
|
-
|
21
|
-
|
17
|
+
'instagram-post': 'Instagram Post',
|
18
|
+
'instagram-story': 'Instagram Story',
|
19
|
+
chatbot: 'Chatbot',
|
20
|
+
template: 'Template',
|
21
|
+
other: 'Other',
|
22
|
+
spotify: 'Spotify',
|
23
|
+
youtube: 'Youtube',
|
22
24
|
'google-search': 'Google search',
|
23
25
|
'google-display': 'Google display',
|
24
|
-
'snapchat-advert': 'Snapchat Advert'
|
26
|
+
'snapchat-advert': 'Snapchat Advert',
|
27
|
+
'digitalorganiser-share': 'Digital Organiser'
|
25
28
|
}
|
26
29
|
|
27
30
|
config.auth_domain = ENV['AUTH_DOMAIN']
|
data/config/routes.rb
CHANGED
@@ -0,0 +1,15 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
class CreateDarjeelinkApiTokens < ActiveRecord::Migration[6.1]
|
4
|
+
def change
|
5
|
+
create_table :darjeelink_api_tokens do |t|
|
6
|
+
t.string :token, null: false
|
7
|
+
t.string :username, null: false
|
8
|
+
t.boolean :active, null: false, default: false
|
9
|
+
t.timestamps
|
10
|
+
end
|
11
|
+
|
12
|
+
add_index(:darjeelink_api_tokens, :username, unique: true)
|
13
|
+
add_index(:darjeelink_api_tokens, :token, unique: true)
|
14
|
+
end
|
15
|
+
end
|
@@ -2,11 +2,7 @@
|
|
2
2
|
|
3
3
|
module Darjeelink
|
4
4
|
class Configuration
|
5
|
-
attr_accessor :domain
|
6
|
-
attr_accessor :source_mediums
|
7
|
-
attr_accessor :auth_domain
|
8
|
-
attr_accessor :rebrandly_api_key
|
9
|
-
attr_accessor :fallback_url
|
5
|
+
attr_accessor :domain, :source_mediums, :auth_domain, :rebrandly_api_key, :fallback_url
|
10
6
|
|
11
7
|
def initialize
|
12
8
|
@domain = nil
|
data/lib/darjeelink/version.rb
CHANGED
metadata
CHANGED
@@ -1,15 +1,29 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: darjeelink
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.13.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- James Hulme
|
8
|
-
autorequire:
|
8
|
+
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2021-11-03 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: omniauth
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - "~>"
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: '1.9'
|
20
|
+
type: :runtime
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - "~>"
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: '1.9'
|
13
27
|
- !ruby/object:Gem::Dependency
|
14
28
|
name: omniauth-google-oauth2
|
15
29
|
requirement: !ruby/object:Gem::Requirement
|
@@ -44,14 +58,14 @@ dependencies:
|
|
44
58
|
requirements:
|
45
59
|
- - "~>"
|
46
60
|
- !ruby/object:Gem::Version
|
47
|
-
version: '
|
61
|
+
version: '6'
|
48
62
|
type: :runtime
|
49
63
|
prerelease: false
|
50
64
|
version_requirements: !ruby/object:Gem::Requirement
|
51
65
|
requirements:
|
52
66
|
- - "~>"
|
53
67
|
- !ruby/object:Gem::Version
|
54
|
-
version: '
|
68
|
+
version: '6'
|
55
69
|
- !ruby/object:Gem::Dependency
|
56
70
|
name: rebrandly
|
57
71
|
requirement: !ruby/object:Gem::Requirement
|
@@ -108,6 +122,20 @@ dependencies:
|
|
108
122
|
- - ">="
|
109
123
|
- !ruby/object:Gem::Version
|
110
124
|
version: '0'
|
125
|
+
- !ruby/object:Gem::Dependency
|
126
|
+
name: brakeman
|
127
|
+
requirement: !ruby/object:Gem::Requirement
|
128
|
+
requirements:
|
129
|
+
- - ">="
|
130
|
+
- !ruby/object:Gem::Version
|
131
|
+
version: '0'
|
132
|
+
type: :development
|
133
|
+
prerelease: false
|
134
|
+
version_requirements: !ruby/object:Gem::Requirement
|
135
|
+
requirements:
|
136
|
+
- - ">="
|
137
|
+
- !ruby/object:Gem::Version
|
138
|
+
version: '0'
|
111
139
|
- !ruby/object:Gem::Dependency
|
112
140
|
name: bundler-audit
|
113
141
|
requirement: !ruby/object:Gem::Requirement
|
@@ -164,7 +192,7 @@ dependencies:
|
|
164
192
|
- - ">="
|
165
193
|
- !ruby/object:Gem::Version
|
166
194
|
version: '0'
|
167
|
-
description:
|
195
|
+
description:
|
168
196
|
email:
|
169
197
|
- james@38degrees.org.uk
|
170
198
|
executables: []
|
@@ -179,6 +207,7 @@ files:
|
|
179
207
|
- app/assets/javascripts/darjeelink/sparkleh.js
|
180
208
|
- app/assets/javascripts/darjeelink/tracking_link_generator.js
|
181
209
|
- app/assets/stylesheets/darjeelink/application.css
|
210
|
+
- app/controllers/darjeelink/api_controller.rb
|
182
211
|
- app/controllers/darjeelink/application_controller.rb
|
183
212
|
- app/controllers/darjeelink/sessions_controller.rb
|
184
213
|
- app/controllers/darjeelink/short_links_controller.rb
|
@@ -188,6 +217,7 @@ files:
|
|
188
217
|
- app/importers/darjeelink/short_link_importer.rb
|
189
218
|
- app/jobs/darjeelink/application_job.rb
|
190
219
|
- app/mailers/darjeelink/application_mailer.rb
|
220
|
+
- app/models/darjeelink/api_token.rb
|
191
221
|
- app/models/darjeelink/application_record.rb
|
192
222
|
- app/models/darjeelink/short_link.rb
|
193
223
|
- app/views/darjeelink/short_links/_short_link_form.erb
|
@@ -196,6 +226,7 @@ files:
|
|
196
226
|
- app/views/darjeelink/short_links/new.html.erb
|
197
227
|
- app/views/darjeelink/tracking_links/new.erb
|
198
228
|
- app/views/layouts/darjeelink/application.html.erb
|
229
|
+
- config/brakeman.ignore
|
199
230
|
- config/initializers/darjeelink.rb
|
200
231
|
- config/initializers/omniauth.rb
|
201
232
|
- config/initializers/rebrandly.rb
|
@@ -204,16 +235,17 @@ files:
|
|
204
235
|
- db/migrate/20190304094710_case_insensitive_index_short_link_shortened_path.rb
|
205
236
|
- db/migrate/20200505220716_rename_portkey_short_links_to_darjeelink_short_links.rb
|
206
237
|
- db/migrate/20200505221026_rename_portkey_short_link_index.rb
|
238
|
+
- db/migrate/20210610083330_create_darjeelink_api_tokens.rb
|
207
239
|
- lib/darjeelink.rb
|
208
240
|
- lib/darjeelink/configuration.rb
|
209
241
|
- lib/darjeelink/engine.rb
|
210
242
|
- lib/darjeelink/version.rb
|
211
243
|
- lib/tasks/darjeelink.rake
|
212
|
-
homepage: https://github.com/
|
244
|
+
homepage: https://github.com/38degrees/darjeelink
|
213
245
|
licenses:
|
214
246
|
- MIT
|
215
247
|
metadata: {}
|
216
|
-
post_install_message:
|
248
|
+
post_install_message:
|
217
249
|
rdoc_options: []
|
218
250
|
require_paths:
|
219
251
|
- lib
|
@@ -221,15 +253,15 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
221
253
|
requirements:
|
222
254
|
- - ">="
|
223
255
|
- !ruby/object:Gem::Version
|
224
|
-
version: '
|
256
|
+
version: '2.7'
|
225
257
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
226
258
|
requirements:
|
227
259
|
- - ">="
|
228
260
|
- !ruby/object:Gem::Version
|
229
261
|
version: '0'
|
230
262
|
requirements: []
|
231
|
-
rubygems_version: 3.
|
232
|
-
signing_key:
|
263
|
+
rubygems_version: 3.1.6
|
264
|
+
signing_key:
|
233
265
|
specification_version: 4
|
234
266
|
summary: URL Shortener
|
235
267
|
test_files: []
|