@nextera.one/softid-sdk 1.0.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 ADDED
@@ -0,0 +1,34 @@
1
+ # SoftID SDK
2
+
3
+ The official SDK for [SoftID](https://softid.org) — the DNS-based identity standard for software.
4
+
5
+ ## Installation
6
+
7
+ ```bash
8
+ npm install @nextera.one/softid-sdk
9
+ ```
10
+
11
+ ## Usage
12
+
13
+ ### Generate a Claim Record
14
+
15
+ ```ts
16
+ import { generateClaimRecord } from '@nextera.one/softid-sdk';
17
+
18
+ const record = generateClaimRecord({ sid: 'MYAPP' });
19
+ // Output: "v=softid1; sid=MYAPP; nonce=01J4..."
20
+ ```
21
+
22
+ ### Verify Ownership (Node.js)
23
+
24
+ ```ts
25
+ import { verifyOwnership } from '@nextera.one/softid-sdk';
26
+
27
+ const result = await verifyOwnership('VUE', 'vuejs.org');
28
+
29
+ if (result.verified) {
30
+ console.log('Verified owner!', result);
31
+ } else {
32
+ console.error('Verification failed', result.error);
33
+ }
34
+ ```
@@ -0,0 +1,80 @@
1
+ export { ulid } from 'ulid';
2
+
3
+ /**
4
+ * SoftID SDK Types
5
+ */
6
+ /**
7
+ * A valid Software Identifier (SID).
8
+ * Format: Upper-case alphanumeric, 2-32 chars.
9
+ */
10
+ type SID = string;
11
+ /**
12
+ * Result of a SoftID verification attempt.
13
+ */
14
+ interface VerificationResult {
15
+ /** Whether the verification was successful */
16
+ verified: boolean;
17
+ /** The SID being verified */
18
+ sid: SID;
19
+ /** The domain that claimed ownership */
20
+ domain: string;
21
+ /** The raw TXT record found (if any) */
22
+ txtRecord?: string;
23
+ /** Error message if verification failed */
24
+ error?: string;
25
+ /** Nonce found in the record */
26
+ nonce?: string;
27
+ }
28
+ /**
29
+ * Represents the components of a parsed SoftID TXT record.
30
+ */
31
+ interface SoftIDRecord {
32
+ v: string;
33
+ sid: SID;
34
+ nonce: string;
35
+ }
36
+ /**
37
+ * Options for generating a claim record.
38
+ */
39
+ interface ClaimOptions {
40
+ sid: SID;
41
+ nonce?: string;
42
+ }
43
+
44
+ /**
45
+ * SoftID SID Logic
46
+ */
47
+ /**
48
+ * Validate if a string is a valid SID.
49
+ */
50
+ declare function isValidSID(sid: string): boolean;
51
+ /**
52
+ * Ensure a string is a valid SID, throwing if not.
53
+ */
54
+ declare function assertValidSID(sid: string): void;
55
+ /**
56
+ * Parse a SoftID TXT record string.
57
+ * Format: v=softid1; sid=MYAPP; nonce=...
58
+ */
59
+ declare function parseTXTRecord(txt: string): Record<string, string> | null;
60
+
61
+ /**
62
+ * SoftID Verification Logic
63
+ */
64
+
65
+ /**
66
+ * Generate the required DNS TXT record value for a claim.
67
+ */
68
+ declare function generateClaimRecord(options: ClaimOptions): string;
69
+ /**
70
+ * Get the expected DNS TXT record name for a domain.
71
+ */
72
+ declare function getClaimName(domain: string): string;
73
+ /**
74
+ * Verify ownership of an SID by a domain.
75
+ * NOTE: This runs only in Node.js environments due to `dns` module usage.
76
+ * For browser usage, a DOH (DNS over HTTPS) adapter would be needed.
77
+ */
78
+ declare function verifyOwnership(sid: string, domain: string): Promise<VerificationResult>;
79
+
80
+ export { type ClaimOptions, type SID, type SoftIDRecord, type VerificationResult, assertValidSID, generateClaimRecord, getClaimName, isValidSID, parseTXTRecord, verifyOwnership };
@@ -0,0 +1,80 @@
1
+ export { ulid } from 'ulid';
2
+
3
+ /**
4
+ * SoftID SDK Types
5
+ */
6
+ /**
7
+ * A valid Software Identifier (SID).
8
+ * Format: Upper-case alphanumeric, 2-32 chars.
9
+ */
10
+ type SID = string;
11
+ /**
12
+ * Result of a SoftID verification attempt.
13
+ */
14
+ interface VerificationResult {
15
+ /** Whether the verification was successful */
16
+ verified: boolean;
17
+ /** The SID being verified */
18
+ sid: SID;
19
+ /** The domain that claimed ownership */
20
+ domain: string;
21
+ /** The raw TXT record found (if any) */
22
+ txtRecord?: string;
23
+ /** Error message if verification failed */
24
+ error?: string;
25
+ /** Nonce found in the record */
26
+ nonce?: string;
27
+ }
28
+ /**
29
+ * Represents the components of a parsed SoftID TXT record.
30
+ */
31
+ interface SoftIDRecord {
32
+ v: string;
33
+ sid: SID;
34
+ nonce: string;
35
+ }
36
+ /**
37
+ * Options for generating a claim record.
38
+ */
39
+ interface ClaimOptions {
40
+ sid: SID;
41
+ nonce?: string;
42
+ }
43
+
44
+ /**
45
+ * SoftID SID Logic
46
+ */
47
+ /**
48
+ * Validate if a string is a valid SID.
49
+ */
50
+ declare function isValidSID(sid: string): boolean;
51
+ /**
52
+ * Ensure a string is a valid SID, throwing if not.
53
+ */
54
+ declare function assertValidSID(sid: string): void;
55
+ /**
56
+ * Parse a SoftID TXT record string.
57
+ * Format: v=softid1; sid=MYAPP; nonce=...
58
+ */
59
+ declare function parseTXTRecord(txt: string): Record<string, string> | null;
60
+
61
+ /**
62
+ * SoftID Verification Logic
63
+ */
64
+
65
+ /**
66
+ * Generate the required DNS TXT record value for a claim.
67
+ */
68
+ declare function generateClaimRecord(options: ClaimOptions): string;
69
+ /**
70
+ * Get the expected DNS TXT record name for a domain.
71
+ */
72
+ declare function getClaimName(domain: string): string;
73
+ /**
74
+ * Verify ownership of an SID by a domain.
75
+ * NOTE: This runs only in Node.js environments due to `dns` module usage.
76
+ * For browser usage, a DOH (DNS over HTTPS) adapter would be needed.
77
+ */
78
+ declare function verifyOwnership(sid: string, domain: string): Promise<VerificationResult>;
79
+
80
+ export { type ClaimOptions, type SID, type SoftIDRecord, type VerificationResult, assertValidSID, generateClaimRecord, getClaimName, isValidSID, parseTXTRecord, verifyOwnership };
package/dist/index.js ADDED
@@ -0,0 +1 @@
1
+ "use strict";var x=Object.create;var c=Object.defineProperty;var v=Object.getOwnPropertyDescriptor;var R=Object.getOwnPropertyNames;var h=Object.getPrototypeOf,D=Object.prototype.hasOwnProperty;var I=(r,t)=>{for(var o in t)c(r,o,{get:t[o],enumerable:!0})},l=(r,t,o,n)=>{if(t&&typeof t=="object"||typeof t=="function")for(let e of R(t))!D.call(r,e)&&e!==o&&c(r,e,{get:()=>t[e],enumerable:!(n=v(t,e))||n.enumerable});return r};var S=(r,t,o)=>(o=r!=null?x(h(r)):{},l(t||!r||!r.__esModule?c(o,"default",{value:r,enumerable:!0}):o,r)),T=r=>l(c({},"__esModule",{value:!0}),r);var X={};I(X,{assertValidSID:()=>f,generateClaimRecord:()=>V,getClaimName:()=>w,isValidSID:()=>u,parseTXTRecord:()=>a,ulid:()=>g.ulid,verifyOwnership:()=>C});module.exports=T(X);var y=/^[A-Z0-9]{2,32}$/;function u(r){return y.test(r)}function f(r){if(!u(r))throw new Error(`Invalid SID format: "${r}". Must be 2-32 uppercase alphanumeric characters.`)}function a(r){if(!r.includes("v=softid1"))return null;let t=r.split(";"),o={};for(let n of t){let e=n.trim(),[s,i]=e.split("=");s&&i&&(o[s.trim()]=i.trim())}return o}var m=require("ulid"),p=S(require("dns")),d=require("util"),$=(0,d.promisify)(p.resolveTxt);function V(r){f(r.sid);let t=r.nonce||(0,m.ulid)();return`v=softid1; sid=${r.sid}; nonce=${t}`}function w(r){return`_softid.${r}`}async function C(r,t){f(r);let o=`_softid.${t}`;try{let n=await $(o);for(let e of n){let s=e.join(""),i=a(s);if(i&&i.v==="softid1"&&i.sid===r)return{verified:!0,sid:r,domain:t,txtRecord:s,nonce:i.nonce}}return{verified:!1,sid:r,domain:t,error:"No matching SoftID TXT record found."}}catch(n){return{verified:!1,sid:r,domain:t,error:`DNS lookup failed: ${n.message}`}}}var g=require("ulid");0&&(module.exports={assertValidSID,generateClaimRecord,getClaimName,isValidSID,parseTXTRecord,ulid,verifyOwnership});
package/dist/index.mjs ADDED
@@ -0,0 +1 @@
1
+ var l=/^[A-Z0-9]{2,32}$/;function u(r){return l.test(r)}function c(r){if(!u(r))throw new Error(`Invalid SID format: "${r}". Must be 2-32 uppercase alphanumeric characters.`)}function f(r){if(!r.includes("v=softid1"))return null;let t=r.split(";"),i={};for(let e of t){let s=e.trim(),[n,o]=s.split("=");n&&o&&(i[n.trim()]=o.trim())}return i}import{ulid as m}from"ulid";import*as a from"dns";import{promisify as p}from"util";var d=p(a.resolveTxt);function h(r){c(r.sid);let t=r.nonce||m();return`v=softid1; sid=${r.sid}; nonce=${t}`}function D(r){return`_softid.${r}`}async function I(r,t){c(r);let i=`_softid.${t}`;try{let e=await d(i);for(let s of e){let n=s.join(""),o=f(n);if(o&&o.v==="softid1"&&o.sid===r)return{verified:!0,sid:r,domain:t,txtRecord:n,nonce:o.nonce}}return{verified:!1,sid:r,domain:t,error:"No matching SoftID TXT record found."}}catch(e){return{verified:!1,sid:r,domain:t,error:`DNS lookup failed: ${e.message}`}}}import{ulid as C}from"ulid";export{c as assertValidSID,h as generateClaimRecord,D as getClaimName,u as isValidSID,f as parseTXTRecord,C as ulid,I as verifyOwnership};
package/package.json ADDED
@@ -0,0 +1,42 @@
1
+ {
2
+ "name": "@nextera.one/softid-sdk",
3
+ "version": "1.0.0",
4
+ "description": "TypeScript/JavaScript SDK for SoftID - DNS-based Software Identity",
5
+ "main": "dist/index.js",
6
+ "module": "dist/index.mjs",
7
+ "types": "dist/index.d.ts",
8
+ "exports": {
9
+ ".": {
10
+ "types": "./dist/index.d.ts",
11
+ "import": "./dist/index.mjs",
12
+ "require": "./dist/index.js"
13
+ }
14
+ },
15
+ "files": [
16
+ "dist",
17
+ "README.md"
18
+ ],
19
+ "scripts": {
20
+ "build": "tsup",
21
+ "test": "vitest run",
22
+ "prepare": "npm run build"
23
+ },
24
+ "keywords": [
25
+ "softid",
26
+ "identity",
27
+ "dns",
28
+ "verification",
29
+ "security"
30
+ ],
31
+ "author": "SoftID Contributors",
32
+ "license": "Apache-2.0",
33
+ "devDependencies": {
34
+ "@types/node": "^20.10.0",
35
+ "tsup": "^8.0.1",
36
+ "typescript": "^5.3.3",
37
+ "vitest": "^1.1.0"
38
+ },
39
+ "dependencies": {
40
+ "ulid": "^2.3.0"
41
+ }
42
+ }