@seamless-auth/express 0.1.2 → 0.3.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 +18 -0
- package/dist/createServer.d.ts +78 -0
- package/dist/createServer.d.ts.map +1 -0
- package/dist/getSeamlessUser.d.ts +4 -0
- package/dist/getSeamlessUser.d.ts.map +1 -0
- package/dist/handlers/admin.d.ts +14 -0
- package/dist/handlers/admin.d.ts.map +1 -0
- package/dist/handlers/bootstrapAdmininvite.d.ts +4 -0
- package/dist/handlers/bootstrapAdmininvite.d.ts.map +1 -0
- package/dist/handlers/finishLogin.d.ts +6 -0
- package/dist/handlers/finishLogin.d.ts.map +1 -0
- package/dist/handlers/finishRegister.d.ts +6 -0
- package/dist/handlers/finishRegister.d.ts.map +1 -0
- package/dist/handlers/internalMetrics.d.ts +9 -0
- package/dist/handlers/internalMetrics.d.ts.map +1 -0
- package/dist/handlers/login.d.ts +4 -0
- package/dist/handlers/login.d.ts.map +1 -0
- package/dist/handlers/logout.d.ts +4 -0
- package/dist/handlers/logout.d.ts.map +1 -0
- package/dist/handlers/me.d.ts +6 -0
- package/dist/handlers/me.d.ts.map +1 -0
- package/dist/handlers/pollMagicLinkConfirmation.d.ts +6 -0
- package/dist/handlers/pollMagicLinkConfirmation.d.ts.map +1 -0
- package/dist/handlers/register.d.ts +4 -0
- package/dist/handlers/register.d.ts.map +1 -0
- package/dist/handlers/requestMagicLink.d.ts +7 -0
- package/dist/handlers/requestMagicLink.d.ts.map +1 -0
- package/dist/handlers/requestOtp.d.ts +7 -0
- package/dist/handlers/requestOtp.d.ts.map +1 -0
- package/dist/handlers/sessions.d.ts +6 -0
- package/dist/handlers/sessions.d.ts.map +1 -0
- package/dist/handlers/systemConfig.d.ts +6 -0
- package/dist/handlers/systemConfig.d.ts.map +1 -0
- package/dist/index.d.ts +9 -197
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +621 -12
- package/dist/internal/buildAuthorization.d.ts +6 -0
- package/dist/internal/buildAuthorization.d.ts.map +1 -0
- package/dist/internal/cookie.d.ts +17 -0
- package/dist/internal/cookie.d.ts.map +1 -0
- package/dist/internal/deliverAuthMessage.d.ts +6 -0
- package/dist/internal/deliverAuthMessage.d.ts.map +1 -0
- package/dist/messaging.d.ts +98 -0
- package/dist/messaging.d.ts.map +1 -0
- package/dist/middleware/ensureCookies.d.ts +16 -0
- package/dist/middleware/ensureCookies.d.ts.map +1 -0
- package/dist/middleware/requireAuth.d.ts +69 -0
- package/dist/middleware/requireAuth.d.ts.map +1 -0
- package/dist/middleware/requireRole.d.ts +36 -0
- package/dist/middleware/requireRole.d.ts.map +1 -0
- package/package.json +7 -5
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
import { Request } from "express";
|
|
2
|
+
import { SeamlessAuthServerOptions } from "../createServer";
|
|
3
|
+
export declare function buildServiceAuthorization(req: Request & {
|
|
4
|
+
cookiePayload?: any;
|
|
5
|
+
}, opts: SeamlessAuthServerOptions): string | undefined;
|
|
6
|
+
//# sourceMappingURL=buildAuthorization.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"buildAuthorization.d.ts","sourceRoot":"","sources":["../../src/internal/buildAuthorization.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,OAAO,EAAE,MAAM,SAAS,CAAC;AAClC,OAAO,EAAE,yBAAyB,EAAE,MAAM,iBAAiB,CAAC;AAE5D,wBAAgB,yBAAyB,CACvC,GAAG,EAAE,OAAO,GAAG;IAAE,aAAa,CAAC,EAAE,GAAG,CAAA;CAAE,EACtC,IAAI,EAAE,yBAAyB,sBAiBhC"}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import { JwtPayload } from "jsonwebtoken";
|
|
2
|
+
import { Response } from "express";
|
|
3
|
+
export interface CookieSignerOptions {
|
|
4
|
+
secret: string;
|
|
5
|
+
secure: boolean;
|
|
6
|
+
sameSite: "lax" | "none";
|
|
7
|
+
}
|
|
8
|
+
export interface SetCookieOptions {
|
|
9
|
+
name: string;
|
|
10
|
+
payload: JwtPayload;
|
|
11
|
+
domain?: string;
|
|
12
|
+
ttlSeconds: number;
|
|
13
|
+
}
|
|
14
|
+
export declare function setSessionCookie(res: Response, opts: SetCookieOptions, signer: CookieSignerOptions): void;
|
|
15
|
+
export declare function clearSessionCookie(res: Response, domain: string | undefined, name: string): void;
|
|
16
|
+
export declare function clearAllCookies(res: Response, domain: string | undefined, ...cookieNames: string[]): void;
|
|
17
|
+
//# sourceMappingURL=cookie.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cookie.d.ts","sourceRoot":"","sources":["../../src/internal/cookie.ts"],"names":[],"mappings":"AAAA,OAAY,EAAE,UAAU,EAAE,MAAM,cAAc,CAAC;AAC/C,OAAO,EAAE,QAAQ,EAAE,MAAM,SAAS,CAAC;AAEnC,MAAM,WAAW,mBAAmB;IAClC,MAAM,EAAE,MAAM,CAAC;IACf,MAAM,EAAE,OAAO,CAAC;IAChB,QAAQ,EAAE,KAAK,GAAG,MAAM,CAAC;CAC1B;AAED,MAAM,WAAW,gBAAgB;IAC/B,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,UAAU,CAAC;IACpB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,UAAU,EAAE,MAAM,CAAC;CACpB;AAED,wBAAgB,gBAAgB,CAC9B,GAAG,EAAE,QAAQ,EACb,IAAI,EAAE,gBAAgB,EACtB,MAAM,EAAE,mBAAmB,QAe5B;AAED,wBAAgB,kBAAkB,CAChC,GAAG,EAAE,QAAQ,EACb,MAAM,EAAE,MAAM,GAAG,SAAS,EAC1B,IAAI,EAAE,MAAM,QAGb;AAED,wBAAgB,eAAe,CAC7B,GAAG,EAAE,QAAQ,EACb,MAAM,EAAE,MAAM,GAAG,SAAS,EAC1B,GAAG,WAAW,EAAE,MAAM,EAAE,QAKzB"}
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
import { AuthDeliveryInstruction, SeamlessAuthMessagingOptions } from "../messaging";
|
|
2
|
+
export declare function deliverAuthMessage(messaging: SeamlessAuthMessagingOptions | undefined, delivery: AuthDeliveryInstruction | undefined): Promise<void>;
|
|
3
|
+
export declare function stripDelivery<T extends {
|
|
4
|
+
delivery?: unknown;
|
|
5
|
+
}>(body: T): Omit<T, "delivery">;
|
|
6
|
+
//# sourceMappingURL=deliverAuthMessage.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"deliverAuthMessage.d.ts","sourceRoot":"","sources":["../../src/internal/deliverAuthMessage.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,uBAAuB,EAEvB,4BAA4B,EAE7B,MAAM,cAAc,CAAC;AA2HtB,wBAAsB,kBAAkB,CACtC,SAAS,EAAE,4BAA4B,GAAG,SAAS,EACnD,QAAQ,EAAE,uBAAuB,GAAG,SAAS,GAC5C,OAAO,CAAC,IAAI,CAAC,CA2Ef;AAED,wBAAgB,aAAa,CAAC,CAAC,SAAS;IAAE,QAAQ,CAAC,EAAE,OAAO,CAAA;CAAE,EAAE,IAAI,EAAE,CAAC,GAAG,IAAI,CAAC,CAAC,EAAE,UAAU,CAAC,CAG5F"}
|
|
@@ -0,0 +1,98 @@
|
|
|
1
|
+
export type MessagingChannel = "email" | "sms";
|
|
2
|
+
export interface DeliveryResult {
|
|
3
|
+
accepted: boolean;
|
|
4
|
+
provider: string;
|
|
5
|
+
channel: MessagingChannel;
|
|
6
|
+
messageId?: string;
|
|
7
|
+
raw?: unknown;
|
|
8
|
+
}
|
|
9
|
+
export interface EmailMessage {
|
|
10
|
+
to: string;
|
|
11
|
+
from?: string;
|
|
12
|
+
subject: string;
|
|
13
|
+
text: string;
|
|
14
|
+
html?: string;
|
|
15
|
+
}
|
|
16
|
+
export interface SmsMessage {
|
|
17
|
+
to: string;
|
|
18
|
+
from?: string;
|
|
19
|
+
body: string;
|
|
20
|
+
}
|
|
21
|
+
export interface EmailTransport {
|
|
22
|
+
readonly name: string;
|
|
23
|
+
send(message: EmailMessage): Promise<DeliveryResult>;
|
|
24
|
+
}
|
|
25
|
+
export interface SmsTransport {
|
|
26
|
+
readonly name: string;
|
|
27
|
+
send(message: SmsMessage): Promise<DeliveryResult>;
|
|
28
|
+
}
|
|
29
|
+
export interface SendOtpEmailInput {
|
|
30
|
+
to: string;
|
|
31
|
+
token: string;
|
|
32
|
+
from?: string;
|
|
33
|
+
subject?: string;
|
|
34
|
+
}
|
|
35
|
+
export interface SendOtpSmsInput {
|
|
36
|
+
to: string;
|
|
37
|
+
token: string | number;
|
|
38
|
+
from?: string;
|
|
39
|
+
}
|
|
40
|
+
export interface SendMagicLinkEmailInput {
|
|
41
|
+
to: string;
|
|
42
|
+
magicLinkUrl: string;
|
|
43
|
+
token?: string;
|
|
44
|
+
from?: string;
|
|
45
|
+
subject?: string;
|
|
46
|
+
}
|
|
47
|
+
export interface SendBootstrapInviteEmailInput {
|
|
48
|
+
to: string;
|
|
49
|
+
inviteUrl: string;
|
|
50
|
+
from?: string;
|
|
51
|
+
subject?: string;
|
|
52
|
+
}
|
|
53
|
+
export interface AuthMessageOverrideContext {
|
|
54
|
+
appName?: string;
|
|
55
|
+
}
|
|
56
|
+
export interface AuthMessageOverrides {
|
|
57
|
+
otpEmail?: (input: SendOtpEmailInput, defaults: EmailMessage, context: AuthMessageOverrideContext) => EmailMessage;
|
|
58
|
+
otpSms?: (input: SendOtpSmsInput, defaults: SmsMessage, context: AuthMessageOverrideContext) => SmsMessage;
|
|
59
|
+
magicLinkEmail?: (input: SendMagicLinkEmailInput, defaults: EmailMessage, context: AuthMessageOverrideContext) => EmailMessage;
|
|
60
|
+
bootstrapInviteEmail?: (input: SendBootstrapInviteEmailInput, defaults: EmailMessage, context: AuthMessageOverrideContext) => EmailMessage;
|
|
61
|
+
}
|
|
62
|
+
export interface AuthMessagingHandlers {
|
|
63
|
+
sendOtpEmail(input: SendOtpEmailInput): Promise<DeliveryResult>;
|
|
64
|
+
sendOtpSms(input: SendOtpSmsInput): Promise<DeliveryResult>;
|
|
65
|
+
sendMagicLinkEmail(input: SendMagicLinkEmailInput): Promise<DeliveryResult>;
|
|
66
|
+
sendBootstrapInviteEmail(input: SendBootstrapInviteEmailInput): Promise<DeliveryResult>;
|
|
67
|
+
}
|
|
68
|
+
export interface SeamlessAuthMessagingOptions {
|
|
69
|
+
email?: EmailTransport;
|
|
70
|
+
sms?: SmsTransport;
|
|
71
|
+
handlers?: Partial<AuthMessagingHandlers>;
|
|
72
|
+
overrides?: AuthMessageOverrides;
|
|
73
|
+
defaults?: {
|
|
74
|
+
appName?: string;
|
|
75
|
+
emailFrom?: string;
|
|
76
|
+
smsFrom?: string;
|
|
77
|
+
};
|
|
78
|
+
}
|
|
79
|
+
export type AuthDeliveryInstruction = {
|
|
80
|
+
kind: "otp_email";
|
|
81
|
+
to: string;
|
|
82
|
+
token: string;
|
|
83
|
+
} | {
|
|
84
|
+
kind: "otp_sms";
|
|
85
|
+
to: string;
|
|
86
|
+
token: string | number;
|
|
87
|
+
} | {
|
|
88
|
+
kind: "magic_link_email";
|
|
89
|
+
to: string;
|
|
90
|
+
token?: string;
|
|
91
|
+
magicLinkUrl: string;
|
|
92
|
+
} | {
|
|
93
|
+
kind: "bootstrap_invite_email";
|
|
94
|
+
to: string;
|
|
95
|
+
token?: string;
|
|
96
|
+
inviteUrl: string;
|
|
97
|
+
};
|
|
98
|
+
//# sourceMappingURL=messaging.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"messaging.d.ts","sourceRoot":"","sources":["../src/messaging.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import { Request, Response, NextFunction } from "express";
|
|
2
|
+
export interface EnsureCookiesMiddlewareOptions {
|
|
3
|
+
authServerUrl: string;
|
|
4
|
+
cookieDomain?: string;
|
|
5
|
+
accessCookieName: string;
|
|
6
|
+
registrationCookieName: string;
|
|
7
|
+
refreshCookieName: string;
|
|
8
|
+
preAuthCookieName: string;
|
|
9
|
+
cookieSecret: string;
|
|
10
|
+
serviceSecret: string;
|
|
11
|
+
issuer: string;
|
|
12
|
+
audience: string;
|
|
13
|
+
keyId: string;
|
|
14
|
+
}
|
|
15
|
+
export declare function createEnsureCookiesMiddleware(opts: EnsureCookiesMiddlewareOptions): (req: Request, res: Response, next: NextFunction) => Promise<void>;
|
|
16
|
+
//# sourceMappingURL=ensureCookies.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ensureCookies.d.ts","sourceRoot":"","sources":["../../src/middleware/ensureCookies.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,QAAQ,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;AAK1D,MAAM,WAAW,8BAA8B;IAC7C,aAAa,EAAE,MAAM,CAAC;IACtB,YAAY,CAAC,EAAE,MAAM,CAAC;IAEtB,gBAAgB,EAAE,MAAM,CAAC;IACzB,sBAAsB,EAAE,MAAM,CAAC;IAC/B,iBAAiB,EAAE,MAAM,CAAC;IAC1B,iBAAiB,EAAE,MAAM,CAAC;IAC1B,YAAY,EAAE,MAAM,CAAC;IACrB,aAAa,EAAE,MAAM,CAAC;IACtB,MAAM,EAAE,MAAM,CAAC;IACf,QAAQ,EAAE,MAAM,CAAC;IACjB,KAAK,EAAE,MAAM,CAAC;CACf;AAED,wBAAgB,6BAA6B,CAC3C,IAAI,EAAE,8BAA8B,IAmBlC,KAAK,OAAO,EACZ,KAAK,QAAQ,EACb,MAAM,YAAY,mBA0BrB"}
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
import { Request, Response, NextFunction } from "express";
|
|
2
|
+
export interface RequireAuthOptions {
|
|
3
|
+
cookieName?: string;
|
|
4
|
+
cookieSecret: string;
|
|
5
|
+
}
|
|
6
|
+
/**
|
|
7
|
+
* Express middleware that enforces authentication using Seamless Auth cookies.
|
|
8
|
+
*
|
|
9
|
+
* This guard verifies the signed access cookie generated by the Seamless Auth
|
|
10
|
+
* server. If the access cookie is valid and unexpired, the decoded session
|
|
11
|
+
* payload is attached to `req.user` and the request proceeds.
|
|
12
|
+
*
|
|
13
|
+
* If the access cookie is expired or missing *but* a valid refresh cookie is
|
|
14
|
+
* present, the middleware automatically attempts a silent token refresh using
|
|
15
|
+
* the Seamless Auth server. When successful, new session cookies are issued and
|
|
16
|
+
* the request continues with an updated `req.user`.
|
|
17
|
+
*
|
|
18
|
+
* If neither the access token nor refresh token can validate the session,
|
|
19
|
+
* the middleware returns a 401 Unauthorized error and prevents further
|
|
20
|
+
* route execution.
|
|
21
|
+
*
|
|
22
|
+
* ### Responsibilities
|
|
23
|
+
* - Validates the Seamless Auth session access cookie
|
|
24
|
+
* - Attempts refresh-token–based session renewal when necessary
|
|
25
|
+
* - Populates `req.user` with the verified session payload
|
|
26
|
+
* - Handles all cookie rewriting during refresh flows
|
|
27
|
+
* - Acts as a request-level authentication guard for API routes
|
|
28
|
+
*
|
|
29
|
+
* ### Cookie Parameters
|
|
30
|
+
* - **cookieName** — Name of the access cookie that holds the signed session JWT
|
|
31
|
+
* - **refreshCookieName** — Name of the refresh cookie used for silent token refresh
|
|
32
|
+
* - **cookieDomain** — Domain or path value applied to issued cookies
|
|
33
|
+
*
|
|
34
|
+
* ### Example
|
|
35
|
+
* ```ts
|
|
36
|
+
* // Protect a route
|
|
37
|
+
* app.get("/api/me", requireAuth(), (req, res) => {
|
|
38
|
+
* res.json({ user: req.user });
|
|
39
|
+
* });
|
|
40
|
+
*
|
|
41
|
+
* // Custom cookie names (if your Seamless Auth server uses overrides)
|
|
42
|
+
* app.use(
|
|
43
|
+
* "/internal",
|
|
44
|
+
* requireAuth("sa_access", "sa_refresh", "mycompany.com"),
|
|
45
|
+
* internalRouter
|
|
46
|
+
* );
|
|
47
|
+
* ```
|
|
48
|
+
*
|
|
49
|
+
* @param cookieName - The access cookie name. Defaults to `"seamless-access"`.
|
|
50
|
+
* @param refreshCookieName - The refresh cookie name used for session rotation. Defaults to `"seamless-refresh"`.
|
|
51
|
+
* @param cookieDomain - Domain or path used when rewriting cookies. Defaults to `"/"`.
|
|
52
|
+
*
|
|
53
|
+
* @returns An Express middleware function that enforces Seamless Auth
|
|
54
|
+
* authentication on incoming requests.
|
|
55
|
+
*/
|
|
56
|
+
export interface RequireAuthOptions {
|
|
57
|
+
cookieName?: string;
|
|
58
|
+
cookieSecret: string;
|
|
59
|
+
}
|
|
60
|
+
/**
|
|
61
|
+
* Express middleware that enforces authentication
|
|
62
|
+
* using an already-issued Seamless Auth access cookie.
|
|
63
|
+
*
|
|
64
|
+
* NOTE:
|
|
65
|
+
* - This middleware does NOT attempt token refresh.
|
|
66
|
+
* - Refresh is handled upstream by ensureCookies().
|
|
67
|
+
*/
|
|
68
|
+
export declare function requireAuth(opts: RequireAuthOptions): (req: Request, res: Response, next: NextFunction) => void;
|
|
69
|
+
//# sourceMappingURL=requireAuth.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"requireAuth.d.ts","sourceRoot":"","sources":["../../src/middleware/requireAuth.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,QAAQ,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;AAI1D,MAAM,WAAW,kBAAkB;IACjC,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,YAAY,EAAE,MAAM,CAAC;CACtB;AACD;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAiDG;AAEH,MAAM,WAAW,kBAAkB;IACjC,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,YAAY,EAAE,MAAM,CAAC;CACtB;AAED;;;;;;;GAOG;AACH,wBAAgB,WAAW,CAAC,IAAI,EAAE,kBAAkB,IAOjC,KAAK,OAAO,EAAE,KAAK,QAAQ,EAAE,MAAM,YAAY,UAoCjE"}
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
import { RequestHandler } from "express";
|
|
2
|
+
/**
|
|
3
|
+
* Express middleware that enforces role-based authorization for Seamless Auth.
|
|
4
|
+
*
|
|
5
|
+
* This middleware assumes `requireAuth()` has already:
|
|
6
|
+
* - authenticated the request
|
|
7
|
+
* - populated `req.user` with the authenticated session payload
|
|
8
|
+
*
|
|
9
|
+
* `requireRole` performs **authorization only**. It does not inspect cookies,
|
|
10
|
+
* verify tokens, or read environment variables.
|
|
11
|
+
*
|
|
12
|
+
* If any of the required roles are present on the user, access is granted.
|
|
13
|
+
* Otherwise, a 403 Forbidden response is returned.
|
|
14
|
+
*
|
|
15
|
+
* * ### Example
|
|
16
|
+
* ```ts
|
|
17
|
+
* // Require a single role
|
|
18
|
+
* app.get("/admin/users",
|
|
19
|
+
* requireAuth(),
|
|
20
|
+
* requireRole("admin"),
|
|
21
|
+
* (req, res) => {
|
|
22
|
+
* res.send("Welcome admin!");
|
|
23
|
+
* }
|
|
24
|
+
* );
|
|
25
|
+
*
|
|
26
|
+
* // Allow any of multiple roles
|
|
27
|
+
* app.post("/settings",
|
|
28
|
+
* requireAuth(),
|
|
29
|
+
* requireRole(["admin", "supervisor"]),
|
|
30
|
+
* updateSettingsHandler
|
|
31
|
+
* );
|
|
32
|
+
*
|
|
33
|
+
* @param requiredRoles - A role or list of roles required to access the route
|
|
34
|
+
*/
|
|
35
|
+
export declare function requireRole(requiredRoles: string | string[]): RequestHandler;
|
|
36
|
+
//# sourceMappingURL=requireRole.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"requireRole.d.ts","sourceRoot":"","sources":["../../src/middleware/requireRole.ts"],"names":[],"mappings":"AAAA,OAAO,EAAmC,cAAc,EAAE,MAAM,SAAS,CAAC;AAE1E;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAgCG;AACH,wBAAgB,WAAW,CAAC,aAAa,EAAE,MAAM,GAAG,MAAM,EAAE,GAAG,cAAc,CAiC5E"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@seamless-auth/express",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.3.0",
|
|
4
4
|
"description": "Express adapter for Seamless Auth passwordless authentication",
|
|
5
5
|
"license": "AGPL-3.0-only",
|
|
6
6
|
"type": "module",
|
|
@@ -23,10 +23,12 @@
|
|
|
23
23
|
"node": ">=18"
|
|
24
24
|
},
|
|
25
25
|
"scripts": {
|
|
26
|
-
"build": "
|
|
26
|
+
"build": "npm run build:js && npm run build:types",
|
|
27
|
+
"build:js": "tsup src/index.ts --format esm --out-dir dist --splitting",
|
|
28
|
+
"build:types": "tsc -p tsconfig.build.json",
|
|
27
29
|
"dev": "tsc --watch",
|
|
28
|
-
"test": "npm run build && NODE_OPTIONS=--experimental-vm-modules jest",
|
|
29
|
-
"test:watch": "npm run build && NODE_OPTIONS=--experimental-vm-modules jest --watch"
|
|
30
|
+
"test": "npm --prefix ../core run build && npm run build && NODE_OPTIONS=--experimental-vm-modules jest",
|
|
31
|
+
"test:watch": "npm --prefix ../core run build && npm run build && NODE_OPTIONS=--experimental-vm-modules jest --watch"
|
|
30
32
|
},
|
|
31
33
|
"repository": {
|
|
32
34
|
"type": "git",
|
|
@@ -37,7 +39,7 @@
|
|
|
37
39
|
"express": ">=4.18.0"
|
|
38
40
|
},
|
|
39
41
|
"dependencies": {
|
|
40
|
-
"@seamless-auth/core": "^0.
|
|
42
|
+
"@seamless-auth/core": "^0.4.0",
|
|
41
43
|
"cookie-parser": "^1.4.6",
|
|
42
44
|
"jsonwebtoken": "^9.0.3"
|
|
43
45
|
},
|