8 files changed
+86
-14
crates/smbcloud-auth-sdk/Cargo.toml
+1
-1
@@ -1,6 +1,6 @@
1
[package]
2
name = "smbcloud-auth-sdk"
3
-version = "0.4.3"
3
+version = "0.4.4"
4
edition = "2024"
5
authors = ["Seto Elkahfi <hej@setoelkahfi.se>"]
6
description = "Client SDK for smbCloud Auth — authenticate your users via smbCloud Auth service."
crates/smbcloud-auth-sdk/src/lib.rs
+1
@@ -5,4 +5,5 @@ pub mod logout;
5
pub mod me;
6
pub mod oidc;
7
pub mod remove;
8
+pub mod reset_password;
9
pub mod signup;
crates/smbcloud-auth-sdk/src/reset_password.rs
new
+38
@@ -0,0 +1,38 @@
1
+use {
2
+ crate::client_credentials::{ClientCredentials, base_url_builder as tenant_base_url_builder},
3
+ reqwest::Client,
4
+ smbcloud_model::{
5
+ error_codes::ErrorResponse,
6
+ forgot::{Args, Email},
7
+ reset_password_response::ResetPasswordResponse,
8
+ },
9
+ smbcloud_network::{environment::Environment, network::request},
10
+};
11
+
12
+/// Requests password-reset instructions for a tenant `AuthUser`.
13
+///
14
+/// Hits `POST /v1/client/users/reset_password`. The endpoint never reveals
15
+/// whether the email belongs to a real account (no enumeration), so it always
16
+/// resolves with a neutral message on success. Calling it again re-issues the
17
+/// reset token, so the same call also serves the "resend reset instructions"
18
+/// flow — the tenant plane has no separate resend endpoint.
19
+pub async fn reset_password_with_client(
20
+ env: Environment,
21
+ client: ClientCredentials<'_>,
22
+ email: String,
23
+) -> Result<ResetPasswordResponse, ErrorResponse> {
24
+ let params = Args {
25
+ user: Email { email },
26
+ };
27
+ let builder = Client::new()
28
+ .post(build_reset_password_url(env, client))
29
+ .json(¶ms)
30
+ .header("User-agent", client.app_id);
31
+ request(builder).await
32
+}
33
+
34
+fn build_reset_password_url(env: Environment, client: ClientCredentials<'_>) -> String {
35
+ let mut url_builder = tenant_base_url_builder(env, client);
36
+ url_builder.add_route("v1/client/users/reset_password");
37
+ url_builder.build()
38
+}
sdk/gems/auth/Cargo.lock
+4
-10
@@ -104,7 +104,7 @@ dependencies = [
104
105
[[package]]
106
name = "auth"
107
-version = "0.4.3"
107
+version = "0.4.4"
108
dependencies = [
109
"magnus",
110
"serde",
@@ -1520,9 +1520,7 @@ checksum = "8ed6a63f02c8539c91a8685a86f4099661ba3da017932f6ebbea6de3f0fa7c90"
1520
1521
[[package]]
1522
name = "smbcloud-auth-sdk"
1523
-version = "0.4.2"
1524
-source = "registry+https://github.com/rust-lang/crates.io-index"
1525
-checksum = "b1c1fa0785ddfb2602f524e49b03d02ab66f35ee5ab9d5da25541283b63af63f"
1523
+version = "0.4.4"
1524
dependencies = [
1525
"base64",
1526
"reqwest",
@@ -1537,9 +1535,7 @@ dependencies = [
1535
1536
[[package]]
1537
name = "smbcloud-model"
1540
-version = "0.4.2"
1541
-source = "registry+https://github.com/rust-lang/crates.io-index"
1542
-checksum = "7dadd0183d4959fccc01435846936d8ba6ea5987805e2a32e21e233383808924"
1538
+version = "0.4.3"
1539
dependencies = [
1540
"chrono",
1541
"log",
@@ -1555,9 +1551,7 @@ dependencies = [
1551
1552
[[package]]
1553
name = "smbcloud-network"
1558
-version = "0.4.2"
1559
-source = "registry+https://github.com/rust-lang/crates.io-index"
1560
-checksum = "813a95c43b1151c055fdb3a57c1a95f92b5d1a452878a87921b2fbca54eaece4"
1554
+version = "0.4.3"
1555
dependencies = [
1556
"clap 4.6.1",
1557
"log",
sdk/gems/auth/ext/auth/Cargo.toml
+1
-1
@@ -1,6 +1,6 @@
1
[package]
2
name = "auth"
3
-version = "0.4.3"
3
+version = "0.4.4"
4
edition = "2024"
5
authors = ["Seto Elkahfi <hej@setoelkahfi.se>"]
6
publish = false
sdk/gems/auth/ext/auth/src/lib.rs
+26
-1
@@ -2,7 +2,8 @@ use magnus::{function, prelude::*, Error, Ruby};
2
use serde::Serialize;
3
use smbcloud_auth_sdk::{
4
client_credentials::ClientCredentials, login::login_with_client, logout::logout_with_client,
5
- me::me_with_client, remove::remove_with_client, signup::signup_with_client,
5
+ me::me_with_client, remove::remove_with_client,
6
+ reset_password::reset_password_with_client, signup::signup_with_client,
7
};
8
use smbcloud_model::{error_codes::ErrorResponse, login::AccountStatus, signup::SignupResult};
9
use smbcloud_network::environment::Environment;
@@ -125,6 +126,26 @@ fn login_with_client_json(
126
})
127
}
128
129
+fn reset_password_with_client_json(
130
+ environment: String,
131
+ app_id: String,
132
+ app_secret: String,
133
+ email: String,
134
+) -> Result<String, Error> {
135
+ let env = parse_environment(environment)?;
136
+ with_runtime(|runtime| {
137
+ let result = runtime.block_on(reset_password_with_client(
138
+ env,
139
+ credentials(&app_id, &app_secret),
140
+ email,
141
+ ));
142
+ match result {
143
+ Ok(result) => to_json(&result),
144
+ Err(error) => Err(raise_error_response(error)),
145
+ }
146
+ })
147
+}
148
+
149
fn me_with_client_json(
150
environment: String,
151
app_id: String,
@@ -195,6 +216,10 @@ fn init(ruby: &Ruby) -> Result<(), Error> {
216
function!(signup_with_client_json, 5),
217
)?;
218
auth.define_singleton_method("__login_with_client", function!(login_with_client_json, 5))?;
219
+ auth.define_singleton_method(
220
+ "__reset_password_with_client",
221
+ function!(reset_password_with_client_json, 4),
222
+ )?;
223
auth.define_singleton_method("__me_with_client", function!(me_with_client_json, 4))?;
224
auth.define_singleton_method(
225
"__logout_with_client",
sdk/gems/auth/lib/auth.rb
+14
@@ -45,6 +45,16 @@ module SmbCloud
45
raise Auth.send(:normalize_error, e)
46
end
47
48
+ # Requests password-reset instructions for the given email. The endpoint
49
+ # never reveals whether the account exists (no enumeration), and calling
50
+ # it again re-issues the token, so this also serves the "resend reset
51
+ # instructions" flow. Returns { code:, message: }.
52
+ def reset_password(email:)
53
+ Auth.send(:parse_json, Auth.__reset_password_with_client(environment, app_id, app_secret, email))
54
+ rescue RuntimeError => e
55
+ raise Auth.send(:normalize_error, e)
56
+ end
57
+
58
def me(access_token:)
59
Auth.send(:parse_json, Auth.__me_with_client(environment, app_id, app_secret, access_token))
60
rescue RuntimeError => e
@@ -77,6 +87,10 @@ module SmbCloud
87
client(environment:, app_id:, app_secret:).login(email:, password:)
88
end
89
90
+ def reset_password_with_client(environment:, app_id:, app_secret:, email:)
91
+ client(environment:, app_id:, app_secret:).reset_password(email:)
92
+ end
93
+
94
def me_with_client(environment:, app_id:, app_secret:, access_token:)
95
client(environment:, app_id:, app_secret:).me(access_token:)
96
end
sdk/gems/auth/lib/auth/version.rb
+1
-1
@@ -1,5 +1,5 @@
1
# frozen_string_literal: true
2
3
module Auth
4
- VERSION = '0.4.3'
4
+ VERSION = '0.4.4'
5
end