@dszp/netsapiens-lib 0.1.4 → 0.1.5

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.
@@ -38,11 +38,27 @@ export interface EligContext {
38
38
  isReseller: boolean;
39
39
  /** Reseller RUNTIME force: bypass ALL soft categories — never HARD, never the email precondition. */
40
40
  force?: boolean;
41
+ /**
42
+ * Credentials are delivered by LOGIN, not email, so the email precondition does not apply. Set this on
43
+ * an SSO/JIT path, where the account is created from the user's own directory credentials on first
44
+ * sign-in and nothing is mailed. It waives ONLY the email precondition — never HARD, never SOFT.
45
+ *
46
+ * The caller decides WHEN to set it; the engine only guarantees the outcome is the same everywhere it
47
+ * is set. A waived result stays distinguishable via `emailWaived`, so a caller can still branch on
48
+ * "eligible, but there is no address to mail anything to".
49
+ */
50
+ emailNotRequired?: boolean;
41
51
  }
42
52
  export type EligTier = 'ok' | 'hard' | 'soft' | 'precondition';
43
53
  export interface EligResult {
44
54
  activatable: boolean;
45
55
  tier: EligTier;
46
56
  reasons: string[];
57
+ /**
58
+ * The user has no email address and `emailNotRequired` waived the precondition. `tier` is `'ok'` —
59
+ * they are eligible — but there is no address, so a caller must not try to mail them credentials.
60
+ * Absent whenever an address is present or the precondition was not reached.
61
+ */
62
+ emailWaived?: true;
47
63
  }
48
64
  export declare function evaluateEligibility(user: EligUser, ctx: EligContext, config: EligibilityConfig): EligResult;
@@ -42,7 +42,17 @@ export function evaluateEligibility(user, ctx, config) {
42
42
  return { activatable: false, tier: 'soft', reasons: [`extension "${user.ext}" matches excluded pattern "${extHit}"`] };
43
43
  }
44
44
  if (blank(user.email)) {
45
- return { activatable: false, tier: 'precondition', reasons: ['an email address is required to activate'] };
45
+ if (!ctx.emailNotRequired) {
46
+ return { activatable: false, tier: 'precondition', reasons: ['an email address is required to activate'] };
47
+ }
48
+ // Waived: credentials arrive by login, not mail. Eligible — but say the address is missing, so a
49
+ // caller that WOULD have mailed something can still tell.
50
+ return {
51
+ activatable: true,
52
+ tier: 'ok',
53
+ reasons: ['no email address (precondition waived: credentials are not emailed)'],
54
+ emailWaived: true,
55
+ };
46
56
  }
47
57
  return { activatable: true, tier: 'ok', reasons: [] };
48
58
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@dszp/netsapiens-lib",
3
- "version": "0.1.4",
3
+ "version": "0.1.5",
4
4
  "description": "Portable, Node-free NetSapiens toolkit: read-only API client, JWT (ns_t) validation, and a snapshot -> FlowGraph -> Mermaid call-flow resolver/renderer. Runs unchanged in a Cloudflare Worker, Node, or the browser.",
5
5
  "type": "module",
6
6
  "license": "MIT",