najm-auth 4.0.7 → 4.0.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.ts CHANGED
@@ -1814,10 +1814,17 @@ type TemporaryCredentialReset = {
1814
1814
  /**
1815
1815
  * Outcome of an administrative mail-out. `emailSent` is what the provider
1816
1816
  * actually reported — never an assumption that sending succeeded.
1817
+ *
1818
+ * `undeliveredLinkLive` is the one case a caller cannot infer: the mail did not
1819
+ * leave AND the link minted for it could not be taken out of circulation, so a
1820
+ * usable link exists that no one received. It is false whenever the mail left
1821
+ * — that link is live on purpose — and false when an undelivered one was
1822
+ * successfully discarded.
1817
1823
  */
1818
1824
  type AdministrativeDelivery = {
1819
1825
  userId: string;
1820
1826
  emailSent: boolean;
1827
+ undeliveredLinkLive: boolean;
1821
1828
  };
1822
1829
  /** Login answer: either a complete session, or a pending credential setup. */
1823
1830
  type LoginResult = (TokenPair & {
@@ -1998,10 +2005,17 @@ declare class AuthService {
1998
2005
  */
1999
2006
  resendInvitation(userId: string): Promise<AdministrativeDelivery>;
2000
2007
  /**
2001
- * Discard a link that was minted but never delivered. A cache that cannot
2002
- * consume atomically is reported rather than pretended away; the caller has
2003
- * already been told the mail did not leave, so the truthful result stands
2004
- * either way.
2008
+ * Take a link that was minted but never delivered out of circulation, and
2009
+ * answer whether it is really gone.
2010
+ *
2011
+ * A `false` from the store is not a failure: compare-and-delete only refuses
2012
+ * when the stored jti is no longer this one, which means a newer mint already
2013
+ * superseded this link and it can no longer be consumed either way. A throw
2014
+ * is the failure — the store was unreachable, the jti it holds is still ours,
2015
+ * and a usable link now exists that nobody received. That does not change
2016
+ * what the caller is told about delivery, but it must not be swallowed: it is
2017
+ * logged as an error and reported up, so the result stays truthful about more
2018
+ * than the mail.
2005
2019
  */
2006
2020
  private discardUndeliveredToken;
2007
2021
  }
package/dist/index.js CHANGED
@@ -4024,10 +4024,8 @@ var AuthService = class AuthService2 {
4024
4024
  } catch (error) {
4025
4025
  this.logger.warn("Administrative password reset email failed", { userId: user.id, error });
4026
4026
  }
4027
- if (!emailSent) {
4028
- await this.discardUndeliveredToken(user.id, jti);
4029
- }
4030
- return { userId: user.id, emailSent };
4027
+ const undeliveredLinkLive = emailSent ? false : !await this.discardUndeliveredToken(user.id, jti);
4028
+ return { userId: user.id, emailSent, undeliveredLinkLive };
4031
4029
  }
4032
4030
  /**
4033
4031
  * Re-send the activation link for an account that is still pending.
@@ -4049,22 +4047,29 @@ var AuthService = class AuthService2 {
4049
4047
  Err12("This account has no email address to send an invitation to", 409);
4050
4048
  }
4051
4049
  const { emailSent, jti } = await this.deliverInvitation(user.id, email2, user.name, user.role);
4052
- if (!emailSent) {
4053
- await this.discardUndeliveredToken(user.id, jti);
4054
- }
4055
- return { userId: user.id, emailSent };
4050
+ const undeliveredLinkLive = emailSent ? false : !await this.discardUndeliveredToken(user.id, jti);
4051
+ return { userId: user.id, emailSent, undeliveredLinkLive };
4056
4052
  }
4057
4053
  /**
4058
- * Discard a link that was minted but never delivered. A cache that cannot
4059
- * consume atomically is reported rather than pretended away; the caller has
4060
- * already been told the mail did not leave, so the truthful result stands
4061
- * either way.
4054
+ * Take a link that was minted but never delivered out of circulation, and
4055
+ * answer whether it is really gone.
4056
+ *
4057
+ * A `false` from the store is not a failure: compare-and-delete only refuses
4058
+ * when the stored jti is no longer this one, which means a newer mint already
4059
+ * superseded this link and it can no longer be consumed either way. A throw
4060
+ * is the failure — the store was unreachable, the jti it holds is still ours,
4061
+ * and a usable link now exists that nobody received. That does not change
4062
+ * what the caller is told about delivery, but it must not be swallowed: it is
4063
+ * logged as an error and reported up, so the result stays truthful about more
4064
+ * than the mail.
4062
4065
  */
4063
4066
  async discardUndeliveredToken(userId, jti) {
4064
4067
  try {
4065
4068
  await this.tokenService.discardSetPasswordToken(userId, jti);
4069
+ return true;
4066
4070
  } catch (error) {
4067
- this.logger.warn("Undelivered set-password token could not be discarded", { userId, error });
4071
+ this.logger.error("Undelivered set-password token is still live", { userId, error });
4072
+ return false;
4068
4073
  }
4069
4074
  }
4070
4075
  };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "najm-auth",
3
- "version": "4.0.7",
3
+ "version": "4.0.8",
4
4
  "description": "Authentication and authorization library for najm framework",
5
5
  "type": "module",
6
6
  "files": [