Its been a while
This commit is contained in:
@@ -1,55 +0,0 @@
|
||||
require "rails_helper"
|
||||
|
||||
RSpec.describe BlacklistedToken, type: :model do
|
||||
let(:user) { User.create!(email: "test@example.com", password: "123456", password_confirmation: "123456") }
|
||||
|
||||
describe "validations" do
|
||||
it "requires jti" do
|
||||
token = BlacklistedToken.new(user: user, exp: 1.hour.from_now)
|
||||
expect(token.valid?).to be false
|
||||
expect(token.errors[:jti]).to include("can't be blank")
|
||||
end
|
||||
|
||||
it "requires exp" do
|
||||
token = BlacklistedToken.new(user: user, jti: SecureRandom.uuid)
|
||||
expect(token.valid?).to be false
|
||||
expect(token.errors[:exp]).to include("can't be blank")
|
||||
end
|
||||
|
||||
it "requires unique jti" do
|
||||
jti = SecureRandom.uuid
|
||||
BlacklistedToken.create!(user: user, jti: jti, exp: 1.hour.from_now)
|
||||
|
||||
duplicate = BlacklistedToken.new(user: user, jti: jti, exp: 1.hour.from_now)
|
||||
expect(duplicate.valid?).to be false
|
||||
expect(duplicate.errors[:jti]).to include("has already been taken")
|
||||
end
|
||||
end
|
||||
|
||||
describe ".blacklisted?" do
|
||||
it "returns true for blacklisted tokens" do
|
||||
jti = SecureRandom.uuid
|
||||
BlacklistedToken.create!(user: user, jti: jti, exp: 1.hour.from_now)
|
||||
|
||||
expect(BlacklistedToken.blacklisted?(jti)).to be true
|
||||
end
|
||||
|
||||
it "returns false for non-blacklisted tokens" do
|
||||
expect(BlacklistedToken.blacklisted?("non-existent-jti")).to be false
|
||||
end
|
||||
end
|
||||
|
||||
describe ".cleanup_expired" do
|
||||
it "removes expired tokens" do
|
||||
expired_token = BlacklistedToken.create!(user: user, jti: SecureRandom.uuid, exp: 1.day.ago)
|
||||
valid_token = BlacklistedToken.create!(user: user, jti: SecureRandom.uuid, exp: 1.hour.from_now)
|
||||
|
||||
expect {
|
||||
BlacklistedToken.cleanup_expired
|
||||
}.to change { BlacklistedToken.count }.by(-1)
|
||||
|
||||
expect(BlacklistedToken.exists?(expired_token.id)).to be false
|
||||
expect(BlacklistedToken.exists?(valid_token.id)).to be true
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -0,0 +1,55 @@
|
||||
require "rails_helper"
|
||||
|
||||
RSpec.describe RetiredToken, type: :model do
|
||||
let(:user) { User.create!(email: "test@example.com", password: "123456", password_confirmation: "123456") }
|
||||
|
||||
describe "validations" do
|
||||
it "requires jti" do
|
||||
token = RetiredToken.new(user: user, exp: 1.hour.from_now)
|
||||
expect(token.valid?).to be false
|
||||
expect(token.errors[:jti]).to include("can't be blank")
|
||||
end
|
||||
|
||||
it "requires exp" do
|
||||
token = RetiredToken.new(user: user, jti: SecureRandom.uuid)
|
||||
expect(token.valid?).to be false
|
||||
expect(token.errors[:exp]).to include("can't be blank")
|
||||
end
|
||||
|
||||
it "requires unique jti" do
|
||||
jti = SecureRandom.uuid
|
||||
RetiredToken.create!(user: user, jti: jti, exp: 1.hour.from_now)
|
||||
|
||||
duplicate = RetiredToken.new(user: user, jti: jti, exp: 1.hour.from_now)
|
||||
expect(duplicate.valid?).to be false
|
||||
expect(duplicate.errors[:jti]).to include("has already been taken")
|
||||
end
|
||||
end
|
||||
|
||||
describe ".retired?" do
|
||||
it "returns true for retired tokens" do
|
||||
jti = SecureRandom.uuid
|
||||
RetiredToken.create!(user: user, jti: jti, exp: 1.hour.from_now)
|
||||
|
||||
expect(RetiredToken.retired?(jti)).to be true
|
||||
end
|
||||
|
||||
it "returns false for non-retired tokens" do
|
||||
expect(RetiredToken.retired?("non-existent-jti")).to be false
|
||||
end
|
||||
end
|
||||
|
||||
describe ".cleanup_expired" do
|
||||
it "removes expired tokens" do
|
||||
expired_token = RetiredToken.create!(user: user, jti: SecureRandom.uuid, exp: 1.day.ago)
|
||||
valid_token = RetiredToken.create!(user: user, jti: SecureRandom.uuid, exp: 1.hour.from_now)
|
||||
|
||||
expect {
|
||||
RetiredToken.cleanup_expired
|
||||
}.to change { RetiredToken.count }.by(-1)
|
||||
|
||||
expect(RetiredToken.exists?(expired_token.id)).to be false
|
||||
expect(RetiredToken.exists?(valid_token.id)).to be true
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -2,7 +2,7 @@ require "swagger_helper"
|
||||
|
||||
RSpec.describe "api/v1/logout", type: :request do
|
||||
path "/api/v1/logout" do
|
||||
post "logs out user and blacklists token" do
|
||||
post "logs out user and retires token" do
|
||||
tags "Auth"
|
||||
consumes "application/json"
|
||||
produces "application/json"
|
||||
@@ -20,7 +20,7 @@ RSpec.describe "api/v1/logout", type: :request do
|
||||
data = JSON.parse(response.body)
|
||||
expect(data["message"]).to include("Successfully logged out")
|
||||
|
||||
# verify token was blacklisted by checking the response
|
||||
# verify token was retired by checking the response
|
||||
# (we can't decode the token variable here as it's scoped to the let block)
|
||||
end
|
||||
end
|
||||
@@ -36,16 +36,16 @@ RSpec.describe "api/v1/logout", type: :request do
|
||||
end
|
||||
end
|
||||
|
||||
describe "blacklisted token rejection" do
|
||||
it "rejects requests with blacklisted tokens" do
|
||||
describe "retired token rejection" do
|
||||
it "rejects requests with retired tokens" do
|
||||
user = User.create!(email: "test@example.com", password: "123456", password_confirmation: "123456")
|
||||
token = JsonWebToken.encode(user_id: user.id)
|
||||
|
||||
# first logout to blacklist the token
|
||||
# first logout to retire the token
|
||||
post "/api/v1/logout", headers: { "Authorization" => "Bearer #{token}" }
|
||||
expect(response).to have_http_status(:ok)
|
||||
|
||||
# try to access protected endpoint with blacklisted token
|
||||
# try to access protected endpoint with retired token
|
||||
get "/api/v1/profile", headers: { "Authorization" => "Bearer #{token}" }
|
||||
expect(response).to have_http_status(:unauthorized)
|
||||
data = JSON.parse(response.body)
|
||||
|
||||
Reference in New Issue
Block a user