mbs-sso-js 0.1.0 → 0.2.0

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/README.md CHANGED
@@ -1,16 +1,16 @@
1
- # mbs-sso-js 0.1.0
1
+ # mbs-sso-js 0.2.0
2
2
 
3
3
  Launch MBS SSO from HTML, React or React Native while keeping OAuth credentials on your application backend. MBS hosts login, enablement, NINAuth, OTP, password setup and consent. Opening a browser is not proof of authentication.
4
4
 
5
5
  ## Install
6
6
 
7
- The package is **not published in the npm registry**. Install the hosted release:
7
+ Install the versioned release from the npm registry once npm finishes processing it:
8
8
 
9
9
  ```sh
10
- npm install https://mbs.d3troit.dev/sdk/mbs-sso-js-0.1.0.tgz
10
+ npm install mbs-sso-js@0.2.0
11
11
  ```
12
12
 
13
- For local development, run `pnpm sdk:build` in the SSO repository, then install its `public/sdk/mbs-sso-js-0.1.0.tgz` file. Node helpers require Node 20+. React and React Native are optional peers; install them only for the adapter you use.
13
+ For local development, run `pnpm sdk:build` in the SSO repository, then install its `public/sdk/mbs-sso-js-0.2.0.tgz` file. Node helpers require Node 20+. React and React Native are optional peers; install them only for the adapter you use.
14
14
 
15
15
  ## HTML
16
16
 
@@ -41,7 +41,7 @@ Uses `Linking.openURL` to open the system browser. Use an absolute HTTPS start U
41
41
  `startUrl` is **your application's backend route**, not the MBS enrollment page. Implement `/auth/mbs/login` and `/auth/mbs/enablement` using the complete Express example in `examples/server.mjs`.
42
42
 
43
43
  1. Obtain a client ID and secret from the MBS team. Register your exact callback URL.
44
- 2. Set `MBS_SSO_BASE_URL=https://mbs.d3troit.dev`, `MBS_SSO_CLIENT_ID`, `MBS_SSO_CLIENT_SECRET`, `MBS_SSO_REDIRECT_URI`, and a strong `SESSION_SECRET` on your backend.
44
+ 2. Set `MBS_SSO_BASE_URL=https://api.mbs.gov.ng`, `MBS_SSO_CLIENT_ID`, `MBS_SSO_CLIENT_SECRET`, `MBS_SSO_REDIRECT_URI`, and a strong `SESSION_SECRET` on your backend.
45
45
  3. `createAuthorizationRequest()` creates random state, nonce and S256 PKCE values. Persist the returned transaction in your server session before redirecting to its `url` (`GET /oauth/authorize`).
46
46
  4. In your registered callback, atomically consume the pending transaction. `exchangeAuthorizationCode()` validates its lifetime, callback origin/path, unique state, error and code, then sends a form POST to `/oauth/token` with the original redirect URI, verifier and client credentials.
47
47
  5. Call `/oauth/userinfo` server-side and create your own application session. Tokens stay server-side. The helper does not verify an ID-token signature; do not use unverified ID-token claims to authenticate users. Use user info as in the example, or a configured OIDC library for ID-token verification.
@@ -54,20 +54,35 @@ The browser adapters know only your start URL. MBS backend improvements remain a
54
54
 
55
55
  Native browser launch and return-link configuration require device validation; this release has not been tested in an iOS/Android emulator.
56
56
 
57
- ## Publish to the npm registry
57
+ Production API base URL: `https://api.mbs.gov.ng`. Sandbox base URL: `https://mbs.d3troit.dev`. Use app credentials registered for the target environment. In MBS SSO Apps, **App ID** is the OAuth `client_id` (`MBS_SSO_CLIENT_ID`) and **App Secret** is the OAuth `client_secret` (`MBS_SSO_CLIENT_SECRET`). Keep the App Secret on your backend. Register your application’s exact callback URI.
58
58
 
59
- Run from the SSO repository root:
59
+ ### Skip business search with an RC number
60
60
 
61
- ```sh
62
- pnpm sdk:build
63
- cd packages/mbs-sso-js
64
- npm login
65
- npm publish --dry-run
66
- npm publish --access public
67
- ```
61
+ Pass `rcNumber: "216879"` to `startSso`, `MbsSsoButton`, or `mountButton`.
62
+ The SDK adds `rc_number` to your backend start URL. Your backend must forward
63
+ that value as `rcNumber` to `createAuthorizationRequest`. The authorization
64
+ service must preserve `rc_number` on its redirect to the SSO enrollment page
65
+ as a URL parameter. Provider-info describes the integrating application and is never used
66
+ as the taxpayer RC source. The enrollment page automatically searches CAC
67
+ and resolves an exact RC match, displaying Business Found or Business not found.
68
+ Users can select Start again to search manually. RC numbers are lookup hints;
69
+ NINAuth verification and authorization checks still apply.
68
70
 
69
- Complete npm's browser login and publishing verification using your own account. The prepublishOnly hook rebuilds the SDK and runs the repository checks and tests. The files allowlist publishes dist, examples and the README. Review the dry-run file list before publishing.
71
+ ```jsx
72
+ <MbsSsoButton startUrl="/auth/mbs/enablement" rcNumber="216879" />
73
+ ```
70
74
 
71
- The unscoped name `mbs-sso-js` must be available or owned by your npm account. If it is not, change the package name to `@YOUR_NPM_SCOPE/mbs-sso-js` and update the example imports and installation instructions accordingly before release. Confirm your organization's ownership and intended license before publishing; this repository does not choose a license for you.
75
+ ```js
76
+ await startSso({ startUrl: "/auth/mbs/enablement", rcNumber: "216879" });
77
+ // Backend start route:
78
+ const { url, transaction } = createAuthorizationRequest({
79
+ baseUrl,
80
+ clientId,
81
+ redirectUri,
82
+ flow: "enablement",
83
+ rcNumber: typeof req.query.rc_number === "string" ? req.query.rc_number : undefined,
84
+ });
85
+ ```
72
86
 
73
- After successful publication, consumers can install `npm install mbs-sso-js` (or the scoped name you chose). Update the hosted documentation and release metadata only after verifying the registry release. For subsequent releases, increment the SDK package version, update the pinned SDK guide/download references, rebuild and publish; npm does not allow overwriting a published name/version pair.
87
+ Omit `rcNumber` or pass an empty string to show manual business search.
88
+ Version 0.2.0 adds this option across browser, React, React Native and server helpers.
package/dist/browser.js CHANGED
@@ -5,6 +5,7 @@ export function mountButton(
5
5
  target,
6
6
  {
7
7
  startUrl,
8
+ rcNumber,
8
9
  label = "Continue with MBS",
9
10
  className = "",
10
11
  style = {},
@@ -32,7 +33,7 @@ export function mountButton(
32
33
  button.setAttribute("aria-busy", "true");
33
34
  status.textContent = "";
34
35
  try {
35
- await startSso({ startUrl, openUrl });
36
+ await startSso({ startUrl, openUrl, rcNumber });
36
37
  } catch (error) {
37
38
  status.textContent = "Could not open MBS SSO. Please try again.";
38
39
  onError?.(error);
package/dist/index.d.ts CHANGED
@@ -1,5 +1,6 @@
1
1
  export interface StartOptions {
2
2
  startUrl: string;
3
+ rcNumber?: string;
3
4
  baseUrl?: string;
4
5
  openUrl?: (url: string) => unknown | Promise<unknown>;
5
6
  }
package/dist/index.js CHANGED
@@ -14,9 +14,12 @@ export function resolveStartUrl(startUrl, baseUrl) {
14
14
  return url.href;
15
15
  }
16
16
 
17
- export async function startSso({ startUrl, openUrl, baseUrl } = {}) {
17
+ export async function startSso({ startUrl, openUrl, baseUrl, rcNumber } = {}) {
18
18
  const browser = typeof window !== "undefined" ? window : undefined;
19
- const url = resolveStartUrl(startUrl, baseUrl ?? browser?.location?.href);
19
+ const target = new URL(resolveStartUrl(startUrl, baseUrl ?? browser?.location?.href));
20
+ if (rcNumber != null && String(rcNumber).trim())
21
+ target.searchParams.set("rc_number", String(rcNumber).trim());
22
+ const url = target.href;
20
23
  if (openUrl) await openUrl(url);
21
24
  else if (browser?.location?.assign) browser.location.assign(url);
22
25
  else throw new Error("Provide openUrl outside a browser.");
@@ -3,6 +3,7 @@ import { Linking, Pressable, Text, View } from "react-native";
3
3
  import { startSso } from "./index.js";
4
4
  export function MbsSsoButton({
5
5
  startUrl,
6
+ rcNumber,
6
7
  baseUrl,
7
8
  label = "Continue with MBS",
8
9
  style,
@@ -19,7 +20,7 @@ export function MbsSsoButton({
19
20
  setPending(true);
20
21
  setError("");
21
22
  try {
22
- await startSso({ startUrl, openUrl, baseUrl });
23
+ await startSso({ startUrl, openUrl, baseUrl, rcNumber });
23
24
  } catch (reason) {
24
25
  setError("Could not open MBS SSO. Please try again.");
25
26
  onError?.(reason);
package/dist/react.js CHANGED
@@ -3,6 +3,7 @@ import { createElement, useState } from "react";
3
3
  import { buttonStyle, startSso } from "./index.js";
4
4
  export function MbsSsoButton({
5
5
  startUrl,
6
+ rcNumber,
6
7
  baseUrl,
7
8
  children,
8
9
  label = "Continue with MBS",
@@ -21,7 +22,7 @@ export function MbsSsoButton({
21
22
  setPending(true);
22
23
  setError("");
23
24
  try {
24
- await startSso({ startUrl, openUrl, baseUrl });
25
+ await startSso({ startUrl, openUrl, baseUrl, rcNumber });
25
26
  } catch (reason) {
26
27
  setError("Could not open MBS SSO. Please try again.");
27
28
  onError?.(reason);
package/dist/server.d.ts CHANGED
@@ -11,6 +11,7 @@ export interface AuthorizationOptions {
11
11
  redirectUri: string;
12
12
  flow?: "login" | "enablement";
13
13
  scope?: string;
14
+ rcNumber?: string;
14
15
  now?: number;
15
16
  }
16
17
  export declare function createAuthorizationRequest(options: AuthorizationOptions): {
package/dist/server.js CHANGED
@@ -7,6 +7,7 @@ export function createAuthorizationRequest({
7
7
  redirectUri,
8
8
  flow = "login",
9
9
  scope = "profile",
10
+ rcNumber,
10
11
  now = Date.now(),
11
12
  }) {
12
13
  if (!clientId || !redirectUri) throw new Error("clientId and redirectUri are required.");
@@ -28,6 +29,8 @@ export function createAuthorizationRequest({
28
29
  code_challenge: createHash("sha256").update(verifier).digest("base64url"),
29
30
  code_challenge_method: "S256",
30
31
  }).toString();
32
+ if (rcNumber != null && String(rcNumber).trim())
33
+ url.searchParams.set("rc_number", String(rcNumber).trim());
31
34
  return {
32
35
  url: url.href,
33
36
  transaction: { state, nonce, verifier, redirectUri, expiresAt: now + 600_000 },
@@ -7,7 +7,7 @@
7
7
  </head>
8
8
  <body>
9
9
  <div id="mbs-login"></div>
10
- <script src="https://mbs.d3troit.dev/sdk/mbs-sso-js-0.1.0.js"></script>
10
+ <script src="https://mbs.d3troit.dev/sdk/mbs-sso-js-0.2.0.js"></script>
11
11
  <script>
12
12
  MbsSso.mountButton("#mbs-login", {
13
13
  startUrl: "/auth/mbs/login",
@@ -25,7 +25,7 @@ app.use(
25
25
  cookie: { httpOnly: true, secure: production, sameSite: "lax", maxAge: 600_000 },
26
26
  }),
27
27
  );
28
- const baseUrl = process.env.MBS_SSO_BASE_URL ?? "https://mbs.d3troit.dev";
28
+ const baseUrl = process.env.MBS_SSO_BASE_URL ?? "https://api.mbs.gov.ng";
29
29
  const redirectUri = process.env.MBS_SSO_REDIRECT_URI;
30
30
  const clientId = process.env.MBS_SSO_CLIENT_ID;
31
31
 
@@ -37,6 +37,7 @@ for (const flow of ["login", "enablement"]) {
37
37
  clientId,
38
38
  redirectUri,
39
39
  flow,
40
+ rcNumber: typeof req.query.rc_number === "string" ? req.query.rc_number : undefined,
40
41
  });
41
42
  req.session.mbs = transaction;
42
43
  // Persist state and verifier before leaving the application.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "mbs-sso-js",
3
- "version": "0.1.0",
3
+ "version": "0.2.0",
4
4
  "description": "MBS SSO browser, React and React Native launch buttons with Node.js authorization helpers",
5
5
  "files": [
6
6
  "dist",