@thorprovider/medusa-extended 1.11.7 → 1.11.8
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.d.mts +98 -2
- package/dist/index.d.ts +98 -2
- package/dist/index.js +174 -2
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +172 -1
- package/dist/index.mjs.map +1 -1
- package/package.json +2 -2
- package/src/index.ts +3 -0
- package/src/recovery.ts +247 -0
package/dist/index.mjs
CHANGED
|
@@ -1873,8 +1873,179 @@ function mapUiMessageStreamToEvents(stream, logger) {
|
|
|
1873
1873
|
}
|
|
1874
1874
|
});
|
|
1875
1875
|
}
|
|
1876
|
+
|
|
1877
|
+
// src/recovery.ts
|
|
1878
|
+
import { createLogger as createLogger3, ProviderAPIError as ProviderAPIError4 } from "@thorprovider/adapters";
|
|
1879
|
+
var RecoveryClient = class {
|
|
1880
|
+
baseUrl;
|
|
1881
|
+
logger;
|
|
1882
|
+
constructor(config) {
|
|
1883
|
+
this.baseUrl = config.baseUrl.replace(/\/$/, "");
|
|
1884
|
+
this.logger = createLogger3("RecoveryClient", config.debug);
|
|
1885
|
+
}
|
|
1886
|
+
// -------------------------------------------------------------------------
|
|
1887
|
+
// Private — HTTP helper
|
|
1888
|
+
// -------------------------------------------------------------------------
|
|
1889
|
+
async request(method, path, body) {
|
|
1890
|
+
const url = `${this.baseUrl}${path}`;
|
|
1891
|
+
this.logger.debug(`[recovery] ${method} ${path}`);
|
|
1892
|
+
const headers = {
|
|
1893
|
+
"Content-Type": "application/json"
|
|
1894
|
+
};
|
|
1895
|
+
const init = {
|
|
1896
|
+
method,
|
|
1897
|
+
headers,
|
|
1898
|
+
...body !== void 0 ? { body: JSON.stringify(body) } : {}
|
|
1899
|
+
};
|
|
1900
|
+
let response;
|
|
1901
|
+
try {
|
|
1902
|
+
response = await fetchBackendWithResilience(url, init);
|
|
1903
|
+
} catch (networkError) {
|
|
1904
|
+
throw new ProviderAPIError4(
|
|
1905
|
+
`[recovery] Network error on ${method} ${path}: ${networkError.message}`,
|
|
1906
|
+
"NETWORK_ERROR",
|
|
1907
|
+
networkError
|
|
1908
|
+
);
|
|
1909
|
+
}
|
|
1910
|
+
if (!response.ok) {
|
|
1911
|
+
let message = `HTTP ${response.status}`;
|
|
1912
|
+
try {
|
|
1913
|
+
const json = await response.json();
|
|
1914
|
+
message = json?.message ?? message;
|
|
1915
|
+
} catch {
|
|
1916
|
+
}
|
|
1917
|
+
throw new ProviderAPIError4(
|
|
1918
|
+
`[recovery] ${method} ${path} failed: ${message}`,
|
|
1919
|
+
`RECOVERY_API_${response.status}`,
|
|
1920
|
+
response.status
|
|
1921
|
+
);
|
|
1922
|
+
}
|
|
1923
|
+
return response.json();
|
|
1924
|
+
}
|
|
1925
|
+
// -------------------------------------------------------------------------
|
|
1926
|
+
// Private — reset token helpers
|
|
1927
|
+
// -------------------------------------------------------------------------
|
|
1928
|
+
/**
|
|
1929
|
+
* Decodes the `entity_id` (email) claim from a Medusa reset-password JWT.
|
|
1930
|
+
*
|
|
1931
|
+
* The JWT is unsigned-trust for this claim: the email is later sent to
|
|
1932
|
+
* `POST /auth/user/emailpass/update`, where Medusa itself re-validates the
|
|
1933
|
+
* token signature and payload before applying the change.
|
|
1934
|
+
*/
|
|
1935
|
+
decodeResetTokenEmail(token) {
|
|
1936
|
+
const parts = token.split(".");
|
|
1937
|
+
if (parts.length !== 3) return null;
|
|
1938
|
+
try {
|
|
1939
|
+
const payload = JSON.parse(Buffer.from(parts[1], "base64url").toString("utf8"));
|
|
1940
|
+
return typeof payload.entity_id === "string" && payload.entity_id.length > 0 ? payload.entity_id : null;
|
|
1941
|
+
} catch {
|
|
1942
|
+
return null;
|
|
1943
|
+
}
|
|
1944
|
+
}
|
|
1945
|
+
// -------------------------------------------------------------------------
|
|
1946
|
+
// Password reset
|
|
1947
|
+
// -------------------------------------------------------------------------
|
|
1948
|
+
/**
|
|
1949
|
+
* Solicita un email de reset de contraseña para el actor `user`
|
|
1950
|
+
* (dropshippers). El backend responde de forma uniforme exista o no la
|
|
1951
|
+
* cuenta (anti enumeración).
|
|
1952
|
+
*
|
|
1953
|
+
* `POST /auth/user/emailpass/reset-password`
|
|
1954
|
+
*/
|
|
1955
|
+
async requestUserPasswordReset(email) {
|
|
1956
|
+
await this.request("POST", "/auth/user/emailpass/reset-password", {
|
|
1957
|
+
identifier: email
|
|
1958
|
+
});
|
|
1959
|
+
}
|
|
1960
|
+
/**
|
|
1961
|
+
* Verifica un token de reset de contraseña sin consumirlo. Devuelve el
|
|
1962
|
+
* email enmascarado (p. ej. `j***@ejemplo.com`) solo cuando `status === 'valid'`.
|
|
1963
|
+
*
|
|
1964
|
+
* `GET /store/dropshipper/auth/reset-password/verify`
|
|
1965
|
+
*/
|
|
1966
|
+
async verifyUserPasswordResetToken(token) {
|
|
1967
|
+
return this.request("GET", `/store/dropshipper/auth/reset-password/verify?token=${encodeURIComponent(token)}`);
|
|
1968
|
+
}
|
|
1969
|
+
/**
|
|
1970
|
+
* Confirma el reset: re-verifica el token (sin consumir), luego consume el
|
|
1971
|
+
* token vía `POST /auth/user/emailpass/update`. El email se deriva del
|
|
1972
|
+
* propio JWT. Nunca devuelve auto-login: al éxito, la UI redirige a /login.
|
|
1973
|
+
*/
|
|
1974
|
+
async confirmUserPasswordReset(token, password) {
|
|
1975
|
+
const verify = await this.verifyUserPasswordResetToken(token);
|
|
1976
|
+
if (verify.status !== "valid") {
|
|
1977
|
+
return { ok: false, status: verify.status };
|
|
1978
|
+
}
|
|
1979
|
+
const email = this.decodeResetTokenEmail(token);
|
|
1980
|
+
if (!email) {
|
|
1981
|
+
return { ok: false, status: "invalid" };
|
|
1982
|
+
}
|
|
1983
|
+
try {
|
|
1984
|
+
const headers = {
|
|
1985
|
+
Authorization: `Bearer ${token}`,
|
|
1986
|
+
"Content-Type": "application/json"
|
|
1987
|
+
};
|
|
1988
|
+
const response = await fetchBackendWithResilience(`${this.baseUrl}/auth/user/emailpass/update`, {
|
|
1989
|
+
method: "POST",
|
|
1990
|
+
headers,
|
|
1991
|
+
body: JSON.stringify({ email, password })
|
|
1992
|
+
});
|
|
1993
|
+
if (!response.ok) {
|
|
1994
|
+
throw new ProviderAPIError4(
|
|
1995
|
+
`[recovery] POST /auth/user/emailpass/update failed: HTTP ${response.status}`,
|
|
1996
|
+
"RECOVERY_API_" + response.status,
|
|
1997
|
+
response.status
|
|
1998
|
+
);
|
|
1999
|
+
}
|
|
2000
|
+
return { ok: true };
|
|
2001
|
+
} catch (error) {
|
|
2002
|
+
this.logger.warn("[recovery] confirmUserPasswordReset failed, re-verifying", error);
|
|
2003
|
+
try {
|
|
2004
|
+
const recheck = await this.verifyUserPasswordResetToken(token);
|
|
2005
|
+
return { ok: false, status: recheck.status };
|
|
2006
|
+
} catch {
|
|
2007
|
+
return { ok: false, status: "invalid" };
|
|
2008
|
+
}
|
|
2009
|
+
}
|
|
2010
|
+
}
|
|
2011
|
+
// -------------------------------------------------------------------------
|
|
2012
|
+
// Account activation
|
|
2013
|
+
// -------------------------------------------------------------------------
|
|
2014
|
+
/**
|
|
2015
|
+
* Verifica un token de activación de cuenta dropshipper sin consumirlo.
|
|
2016
|
+
*
|
|
2017
|
+
* `GET /store/dropshipper/applications/activate/verify`
|
|
2018
|
+
*/
|
|
2019
|
+
async verifyActivationToken(token) {
|
|
2020
|
+
return this.request("GET", `/store/dropshipper/applications/activate/verify?token=${encodeURIComponent(token)}`);
|
|
2021
|
+
}
|
|
2022
|
+
/**
|
|
2023
|
+
* Activa la cuenta: re-verifica el token (sin consumir), luego consume el
|
|
2024
|
+
* token vía `POST /store/dropshipper/applications/activate` y establece la
|
|
2025
|
+
* contraseña inicial. Al éxito, la UI redirige a /login sin auto-login.
|
|
2026
|
+
*/
|
|
2027
|
+
async activateAccount(token, password) {
|
|
2028
|
+
const verify = await this.verifyActivationToken(token);
|
|
2029
|
+
if (verify.status !== "valid") {
|
|
2030
|
+
return { ok: false, status: verify.status };
|
|
2031
|
+
}
|
|
2032
|
+
try {
|
|
2033
|
+
await this.request("POST", "/store/dropshipper/applications/activate", { token, password });
|
|
2034
|
+
return { ok: true };
|
|
2035
|
+
} catch (error) {
|
|
2036
|
+
this.logger.warn("[recovery] activateAccount failed, re-verifying", error);
|
|
2037
|
+
try {
|
|
2038
|
+
const recheck = await this.verifyActivationToken(token);
|
|
2039
|
+
return { ok: false, status: recheck.status };
|
|
2040
|
+
} catch {
|
|
2041
|
+
return { ok: false, status: "invalid" };
|
|
2042
|
+
}
|
|
2043
|
+
}
|
|
2044
|
+
}
|
|
2045
|
+
};
|
|
1876
2046
|
export {
|
|
1877
2047
|
DropshipperClient,
|
|
1878
|
-
MedusaAdminClient
|
|
2048
|
+
MedusaAdminClient,
|
|
2049
|
+
RecoveryClient
|
|
1879
2050
|
};
|
|
1880
2051
|
//# sourceMappingURL=index.mjs.map
|