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 +32 -17
- package/dist/browser.js +2 -1
- package/dist/index.d.ts +1 -0
- package/dist/index.js +5 -2
- package/dist/react-native.js +2 -1
- package/dist/react.js +2 -1
- package/dist/server.d.ts +1 -0
- package/dist/server.js +3 -0
- package/examples/index.html +1 -1
- package/examples/server.mjs +2 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -1,16 +1,16 @@
|
|
|
1
|
-
# mbs-sso-js 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
|
-
|
|
7
|
+
Install the versioned release from the npm registry once npm finishes processing it:
|
|
8
8
|
|
|
9
9
|
```sh
|
|
10
|
-
npm install
|
|
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.
|
|
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.
|
|
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
|
-
|
|
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
|
-
|
|
59
|
+
### Skip business search with an RC number
|
|
60
60
|
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
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
|
-
|
|
71
|
+
```jsx
|
|
72
|
+
<MbsSsoButton startUrl="/auth/mbs/enablement" rcNumber="216879" />
|
|
73
|
+
```
|
|
70
74
|
|
|
71
|
-
|
|
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
|
-
|
|
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
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
|
|
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.");
|
package/dist/react-native.js
CHANGED
|
@@ -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
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 },
|
package/examples/index.html
CHANGED
|
@@ -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.
|
|
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",
|
package/examples/server.mjs
CHANGED
|
@@ -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.
|
|
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.
|