From fbe8b1fbac19887388d5eecfd287d1abb4c98edf Mon Sep 17 00:00:00 2001 From: Justin Tan Date: Mon, 17 Mar 2025 15:50:50 -0600 Subject: [PATCH 1/6] Permit remember_me params and pass to blueprint --- app/blueprints/api/v1/session_blueprint.rb | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/app/blueprints/api/v1/session_blueprint.rb b/app/blueprints/api/v1/session_blueprint.rb index ad62dffe9c..4bac419878 100644 --- a/app/blueprints/api/v1/session_blueprint.rb +++ b/app/blueprints/api/v1/session_blueprint.rb @@ -14,8 +14,12 @@ class Api::V1::SessionBlueprint < Blueprinter::Base token.return_new_api_token![:api_token] end - field :refresh_token do |user| + field :refresh_token do |user, options| token = user.api_credential - token.return_new_refresh_token![:refresh_token] + if options[:remember_me] + token.return_new_refresh_token!(true)[:refresh_token] + else + token.return_new_refresh_token!(false)[:refresh_token] + end end end From 35d07834098eb03bbabde89c1c85881eb830e0a1 Mon Sep 17 00:00:00 2001 From: Justin Tan Date: Mon, 17 Mar 2025 15:52:41 -0600 Subject: [PATCH 2/6] Add remember_me param to api controller --- app/controllers/api/v1/users/sessions_controller.rb | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/app/controllers/api/v1/users/sessions_controller.rb b/app/controllers/api/v1/users/sessions_controller.rb index b72c05c7f8..4fb8dd60d2 100644 --- a/app/controllers/api/v1/users/sessions_controller.rb +++ b/app/controllers/api/v1/users/sessions_controller.rb @@ -2,7 +2,7 @@ class Api::V1::Users::SessionsController < Api::V1::BaseController def create load_resource if @user - render json: Api::V1::SessionBlueprint.render(@user), status: 201 + render json: Api::V1::SessionBlueprint.render(@user, remember_me: user_params[:remember_me]), status: 201 else render json: {message: "Incorrect email or password."}, status: 401 end @@ -27,7 +27,7 @@ def destroy private def user_params - params.permit(:email, :password) + params.permit(:email, :password, :remember_me) end def load_resource From 8c0e87b4165b3459a32fb3bfc345e3c6392c9f87 Mon Sep 17 00:00:00 2001 From: Justin Tan Date: Mon, 17 Mar 2025 15:53:28 -0600 Subject: [PATCH 3/6] Update return_new_refresh_token with remember_me --- app/models/api_credential.rb | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/app/models/api_credential.rb b/app/models/api_credential.rb index adcf3b5435..15cd251e57 100644 --- a/app/models/api_credential.rb +++ b/app/models/api_credential.rb @@ -22,8 +22,13 @@ def return_new_api_token! {api_token: new_token} end - def return_new_refresh_token! + def return_new_refresh_token! (remember_me) new_token = generate_refresh_token + if remember_me + update_column(:refresh_token_expires_at, 1.year.from_now) + else + update_column(:refresh_token_expires_at, 30.days.from_now) + end update_column(:refresh_token_digest, refresh_token_digest) {refresh_token: new_token} end From cbb6ce617b05dfa79a5edcb9546a1963e54d8875 Mon Sep 17 00:00:00 2001 From: Justin Tan Date: Mon, 17 Mar 2025 15:54:52 -0600 Subject: [PATCH 4/6] Tests for refreshtoken remember_me --- spec/models/api_credential_spec.rb | 26 +++++++++++++++++++++----- 1 file changed, 21 insertions(+), 5 deletions(-) diff --git a/spec/models/api_credential_spec.rb b/spec/models/api_credential_spec.rb index 99266e3cf3..4180db7968 100644 --- a/spec/models/api_credential_spec.rb +++ b/spec/models/api_credential_spec.rb @@ -20,7 +20,7 @@ describe "#authenticate_refresh_token" do it "returns true for a valid refresh_token" do - refresh_token = api_credential.return_new_refresh_token![:refresh_token] + refresh_token = api_credential.return_new_refresh_token!(false)[:refresh_token] expect(api_credential.authenticate_refresh_token(refresh_token)).to be true end @@ -47,13 +47,13 @@ describe "#return_new_refresh_token!" do it "updates the refresh_token digest" do old_digest = api_credential.refresh_token_digest - api_credential.return_new_refresh_token![:refresh_token] + api_credential.return_new_refresh_token!(false)[:refresh_token] api_credential.reload expect(api_credential.refresh_token_digest).not_to eq(old_digest) end it "sets a new refresh_token" do - new_token = api_credential.return_new_refresh_token![:refresh_token] + new_token = api_credential.return_new_refresh_token!(false)[:refresh_token] expect(new_token).not_to be_nil end @@ -95,7 +95,7 @@ describe "#generate_refresh_token" do it "creates a secure hashed refresh_token" do api_credential.refresh_token_digest - refresh_token = api_credential.return_new_refresh_token![:refresh_token] + refresh_token = api_credential.return_new_refresh_token!(false)[:refresh_token] expect(api_credential.refresh_token_digest).to eq(Digest::SHA256.hexdigest(refresh_token)) end @@ -112,10 +112,26 @@ describe "#revoke_refresh_token" do it "sets refresh token to nil" do - api_credential.return_new_refresh_token![:refresh_token] + api_credential.return_new_refresh_token!(false)[:refresh_token] api_credential.revoke_refresh_token expect(api_credential.refresh_token_digest).to be_nil end end + describe "#generate_refresh_token_with_rememberme" do + it "updates token to be valid for 1 year" do + api_credential.refresh_token_digest + refresh_token = api_credential.return_new_refresh_token!(true)[:refresh_token] + + expect(api_credential.refresh_token_expires_at).to be_within(1.minutes).of(1.year.from_now) + end +end + describe "#generate_refresh_token_without_rememberme" do + it "updates token to be valid for 30 days" do + api_credential.refresh_token_digest + refresh_token = api_credential.return_new_refresh_token!(false)[:refresh_token] + + expect(api_credential.refresh_token_expires_at).to be_within(1.minutes).of(30.days.from_now) + end +end end From b50066fc57379efd50c99cb0d1dcfe5b9ed4311e Mon Sep 17 00:00:00 2001 From: Justin Tan Date: Mon, 17 Mar 2025 19:19:27 -0600 Subject: [PATCH 5/6] Style fixes --- app/models/api_credential.rb | 2 +- spec/models/api_credential_spec.rb | 20 +++++++++++--------- 2 files changed, 12 insertions(+), 10 deletions(-) diff --git a/app/models/api_credential.rb b/app/models/api_credential.rb index 15cd251e57..bdad93b2f5 100644 --- a/app/models/api_credential.rb +++ b/app/models/api_credential.rb @@ -22,7 +22,7 @@ def return_new_api_token! {api_token: new_token} end - def return_new_refresh_token! (remember_me) + def return_new_refresh_token!(remember_me) new_token = generate_refresh_token if remember_me update_column(:refresh_token_expires_at, 1.year.from_now) diff --git a/spec/models/api_credential_spec.rb b/spec/models/api_credential_spec.rb index 4180db7968..bf9eb33061 100644 --- a/spec/models/api_credential_spec.rb +++ b/spec/models/api_credential_spec.rb @@ -118,20 +118,22 @@ expect(api_credential.refresh_token_digest).to be_nil end end + describe "#generate_refresh_token_with_rememberme" do - it "updates token to be valid for 1 year" do - api_credential.refresh_token_digest - refresh_token = api_credential.return_new_refresh_token!(true)[:refresh_token] + it "updates token to be valid for 1 year" do + api_credential.refresh_token_digest + refresh_token = api_credential.return_new_refresh_token!(true)[:refresh_token] - expect(api_credential.refresh_token_expires_at).to be_within(1.minutes).of(1.year.from_now) + expect(api_credential.refresh_token_expires_at).to be_within(1.minutes).of(1.year.from_now) + end end -end + describe "#generate_refresh_token_without_rememberme" do - it "updates token to be valid for 30 days" do - api_credential.refresh_token_digest - refresh_token = api_credential.return_new_refresh_token!(false)[:refresh_token] + it "updates token to be valid for 30 days" do + api_credential.refresh_token_digest + refresh_token = api_credential.return_new_refresh_token!(false)[:refresh_token] expect(api_credential.refresh_token_expires_at).to be_within(1.minutes).of(30.days.from_now) + end end end -end From c028074e2358bb8743658700469a0ab673d6b918 Mon Sep 17 00:00:00 2001 From: Justin Tan Date: Mon, 17 Mar 2025 19:29:13 -0600 Subject: [PATCH 6/6] Lint --- spec/models/api_credential_spec.rb | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/spec/models/api_credential_spec.rb b/spec/models/api_credential_spec.rb index bf9eb33061..f89178360e 100644 --- a/spec/models/api_credential_spec.rb +++ b/spec/models/api_credential_spec.rb @@ -122,7 +122,7 @@ describe "#generate_refresh_token_with_rememberme" do it "updates token to be valid for 1 year" do api_credential.refresh_token_digest - refresh_token = api_credential.return_new_refresh_token!(true)[:refresh_token] + api_credential.return_new_refresh_token!(true)[:refresh_token] expect(api_credential.refresh_token_expires_at).to be_within(1.minutes).of(1.year.from_now) end @@ -131,9 +131,9 @@ describe "#generate_refresh_token_without_rememberme" do it "updates token to be valid for 30 days" do api_credential.refresh_token_digest - refresh_token = api_credential.return_new_refresh_token!(false)[:refresh_token] + api_credential.return_new_refresh_token!(false)[:refresh_token] - expect(api_credential.refresh_token_expires_at).to be_within(1.minutes).of(30.days.from_now) + expect(api_credential.refresh_token_expires_at).to be_within(1.minutes).of(30.days.from_now) end end end