Skip to content

Commit 824ff03

Browse files
committed
some exports cleanup
still a WIP to see if I can continue to attack circular architecture
1 parent 7370b88 commit 824ff03

File tree

17 files changed

+262
-287
lines changed

17 files changed

+262
-287
lines changed

src/binding-post.ts

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -4,13 +4,13 @@
44
* @desc Binding-level API, declare the functions using POST binding
55
*/
66

7-
import type { BindingContext, Entity } from './entity';
8-
import type { IdentityProvider } from './entity-idp';
7+
import type { BindingContext } from './binding';
8+
import type { Entity, ParsedLogoutRequest } from './entity';
9+
import type { IdentityProvider, ParsedLoginRequest } from './entity-idp';
910
import type { ServiceProvider } from './entity-sp';
1011
import { SamlifyError, SamlifyErrorCode } from './error';
1112
import type { FlowResult } from './flow';
12-
import libsaml, { CustomTagReplacement } from './libsaml';
13-
import type { ParsedLoginRequest, ParsedLogoutRequest } from './types';
13+
import { CustomTagReplacement, libsaml } from './libsaml';
1414
import { BindingNamespace, StatusCode } from './urn';
1515
import { base64Decode, base64Encode, isNonEmptyArray } from './utility';
1616

src/binding-redirect.ts

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3,13 +3,13 @@
33
* @author tngan
44
* @desc Binding-level API, declare the functions using Redirect binding
55
*/
6-
import type { BindingContext, Entity } from './entity';
6+
import type { BindingContext } from './binding';
7+
import type { Entity, ParsedLogoutRequest } from './entity';
78
import type { IdentityProvider } from './entity-idp';
89
import type { ServiceProvider } from './entity-sp';
910
import { SamlifyError, SamlifyErrorCode } from './error';
1011
import type { FlowResult } from './flow';
11-
import libsaml, { CustomTagReplacement } from './libsaml';
12-
import type { ParsedLogoutRequest, RequestSignatureAlgorithm } from './types';
12+
import { CustomTagReplacement, libsaml, RequestSignatureAlgorithm } from './libsaml';
1313
import { BindingNamespace, StatusCode, wording } from './urn';
1414
import { base64Encode, deflateString } from './utility';
1515

src/binding.ts

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
export interface ESamlHttpRequest {
2+
query?: any;
3+
body?: any;
4+
octetString?: string;
5+
}
6+
7+
export interface BindingContext {
8+
context: string;
9+
id: string;
10+
}
11+
12+
export interface PostBindingContext extends BindingContext {
13+
relayState?: string;
14+
entityEndpoint: string;
15+
type: 'SAMLRequest' | 'SAMLResponse';
16+
}

src/entity-idp.ts

Lines changed: 29 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -3,20 +3,38 @@
33
* @author tngan
44
* @desc Declares the actions taken by identity provider
55
*/
6+
import type { ESamlHttpRequest } from './binding';
67
import postBinding from './binding-post';
7-
import { Entity, ESamlHttpRequest } from './entity';
8+
import { Entity, EntitySettings } from './entity';
89
import type { ServiceProvider } from './entity-sp';
910
import { SamlifyError, SamlifyErrorCode } from './error';
1011
import { flow, FlowResult } from './flow';
11-
import type { CustomTagReplacement } from './libsaml';
12-
import metadataIdp, { MetadataIdp } from './metadata-idp';
13-
import type { IdentityProviderSettings, ParsedLoginRequest } from './types';
12+
import type { CustomTagReplacement, LoginResponseTemplate } from './libsaml';
13+
import type { SSOService } from './metadata';
14+
import { metadataIdp, MetadataIdp } from './metadata-idp';
1415
import { BindingNamespace, ParserType } from './urn';
1516

17+
export interface IdentityProviderSettings extends EntitySettings {
18+
/** template of login response */
19+
loginResponseTemplate?: LoginResponseTemplate;
20+
21+
singleSignOnService?: SSOService[];
22+
wantAuthnRequestsSigned?: boolean;
23+
wantLogoutRequestSignedResponseSigned?: boolean;
24+
}
25+
26+
export interface ParsedLoginRequest {
27+
authnContextClassRef?: string;
28+
issuer?: string;
29+
nameIDPolicy?: { format?: string; allowCreate?: string };
30+
request?: { id?: string; issueInstant?: string; destination?: string; assertionConsumerServiceUrl?: string };
31+
signature?: string;
32+
}
33+
1634
/**
1735
* Identity prvider can be configured using either metadata importing or idpSetting
1836
*/
19-
export default function (props: IdentityProviderSettings) {
37+
export function identityProvider(props: IdentityProviderSettings) {
2038
return new IdentityProvider(props);
2139
}
2240

@@ -25,15 +43,13 @@ export default function (props: IdentityProviderSettings) {
2543
*/
2644
export class IdentityProvider extends Entity<IdentityProviderSettings, MetadataIdp> {
2745
constructor(idpSettings: IdentityProviderSettings) {
28-
const entitySettings = Object.assign(
29-
{
30-
wantAuthnRequestsSigned: false,
31-
tagPrefix: {
32-
encryptedAssertion: 'saml',
33-
},
46+
const entitySettings = {
47+
wantAuthnRequestsSigned: false,
48+
tagPrefix: {
49+
encryptedAssertion: 'saml',
3450
},
35-
idpSettings
36-
);
51+
...idpSettings,
52+
};
3753
const entityMeta = metadataIdp(entitySettings.metadata || entitySettings);
3854
// setting with metadata has higher precedence
3955
entitySettings.wantAuthnRequestsSigned = entityMeta.isWantAuthnRequestsSigned();

src/entity-sp.ts

Lines changed: 38 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -3,21 +3,47 @@
33
* @author tngan
44
* @desc Declares the actions taken by service provider
55
*/
6+
import type { BindingContext, ESamlHttpRequest, PostBindingContext } from './binding';
67
import postBinding from './binding-post';
78
import redirectBinding from './binding-redirect';
8-
import { BindingContext, Entity, ESamlHttpRequest, PostBindingContext } from './entity';
9+
import { Entity, EntitySettings } from './entity';
910
import type { IdentityProvider } from './entity-idp';
1011
import { SamlifyError, SamlifyErrorCode } from './error';
1112
import { flow, FlowResult } from './flow';
12-
import type { CustomTagReplacement } from './libsaml';
13-
import metadataSp, { MetadataSp } from './metadata-sp';
14-
import type { ParsedLoginResponse, ServiceProviderSettings } from './types';
15-
import { BindingNamespace, ParserType } from './urn';
13+
import type { CustomTagReplacement, SAMLDocumentTemplate } from './libsaml';
14+
import type { SSOService } from './metadata';
15+
import { metadataSp, MetadataSp } from './metadata-sp';
16+
import { BindingNamespace, MetaElement, ParserType } from './urn';
17+
18+
export interface ServiceProviderSettings extends EntitySettings {
19+
assertionConsumerService?: SSOService[];
20+
authnRequestsSigned?: boolean;
21+
elementsOrder?: (keyof MetaElement)[];
22+
wantAssertionsSigned?: boolean;
23+
wantMessageSigned?: boolean;
24+
25+
/** template of login request */
26+
loginRequestTemplate?: SAMLDocumentTemplate;
27+
28+
allowCreate?: boolean;
29+
// will be deprecated soon
30+
relayState?: string;
31+
}
32+
33+
export interface ParsedLoginResponse {
34+
attributes?: Record<string, string>;
35+
audience?: string;
36+
conditions?: { notBefore: string; notOnOrAfter: string };
37+
issuer?: string;
38+
nameID?: string;
39+
response?: { id?: string; issueInstant?: string; destination?: string; inResponseTo?: string };
40+
sessionIndex?: { authnInstant?: string; sessionNotOnOrAfter?: string; sessionIndex?: string };
41+
}
1642

1743
/*
1844
* @desc interface function
1945
*/
20-
export default function (props: ServiceProviderSettings) {
46+
export function serviceProvider(props: ServiceProviderSettings) {
2147
return new ServiceProvider(props);
2248
}
2349

@@ -31,14 +57,12 @@ export class ServiceProvider extends Entity<ServiceProviderSettings, MetadataSp>
3157
* @param {object} spSettings settings of service provider
3258
*/
3359
constructor(spSettings: ServiceProviderSettings) {
34-
const entitySettings = Object.assign(
35-
{
36-
authnRequestsSigned: false,
37-
wantAssertionsSigned: false,
38-
wantMessageSigned: false,
39-
},
40-
spSettings
41-
);
60+
const entitySettings = {
61+
authnRequestsSigned: false,
62+
wantAssertionsSigned: false,
63+
wantMessageSigned: false,
64+
...spSettings,
65+
};
4266
const entityMeta = metadataSp(entitySettings.metadata || entitySettings);
4367
// setting with metadata has higher precedence
4468
entitySettings.authnRequestsSigned = entityMeta.isAuthnRequestSigned();

src/entity.ts

Lines changed: 60 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -4,14 +4,22 @@
44
* @desc An abstraction for identity provider and service provider.
55
*/
66
import { v4 as uuid } from 'uuid';
7+
import type { BindingContext, ESamlHttpRequest, PostBindingContext } from './binding';
78
import postBinding from './binding-post';
89
import redirectBinding from './binding-redirect';
910
import { SamlifyError, SamlifyErrorCode } from './error';
1011
import { flow, FlowResult } from './flow';
11-
import type { CustomTagReplacement } from './libsaml';
12-
import type { Metadata } from './metadata';
13-
import type { EntitySettings, ParsedLogoutRequest, ParsedLogoutResponse } from './types';
14-
import { algorithms, BindingNamespace, messageConfigurations, ParserType } from './urn';
12+
import type {
13+
CustomTagReplacement,
14+
EncryptionAlgorithm,
15+
KeyEncryptionAlgorithm,
16+
LogoutResponseTemplate,
17+
RequestSignatureAlgorithm,
18+
SAMLDocumentTemplate,
19+
SignatureConfig,
20+
} from './libsaml';
21+
import type { Metadata, SSOService } from './metadata';
22+
import { algorithms, BindingNamespace, messageConfigurations, MessageSignatureOrder, ParserType } from './urn';
1523
import { isNonEmptyArray, isString } from './utility';
1624

1725
const dataEncryptionAlgorithm = algorithms.encryption.data;
@@ -32,27 +40,58 @@ const defaultEntitySetting = {
3240
relayState: '',
3341
} as const;
3442

35-
export interface ESamlHttpRequest {
36-
query?: any;
37-
body?: any;
38-
octetString?: string;
39-
}
43+
export interface EntitySettings {
44+
metadata?: string | Buffer;
45+
entityID?: string;
46+
singleLogoutService?: SSOService[];
47+
48+
isAssertionEncrypted?: boolean;
49+
50+
/** signature algorithm */
51+
requestSignatureAlgorithm?: RequestSignatureAlgorithm;
52+
dataEncryptionAlgorithm?: EncryptionAlgorithm;
53+
keyEncryptionAlgorithm?: KeyEncryptionAlgorithm;
54+
55+
messageSigningOrder?: MessageSignatureOrder;
56+
signatureConfig?: SignatureConfig;
57+
transformationAlgorithms?: string[];
58+
wantLogoutRequestSigned?: boolean;
59+
wantLogoutResponseSigned?: boolean;
60+
61+
signingCert?: string | Buffer;
62+
privateKey?: string | Buffer;
63+
privateKeyPass?: string;
64+
65+
encryptCert?: string | Buffer;
66+
encPrivateKey?: string | Buffer;
67+
encPrivateKeyPass?: string;
68+
69+
/** template of logout request */
70+
logoutRequestTemplate?: SAMLDocumentTemplate;
71+
/** template of logout response */
72+
logoutResponseTemplate?: LogoutResponseTemplate;
73+
74+
nameIDFormat?: string[];
75+
// https://github.com/tngan/samlify/issues/337
76+
clockDrifts?: [number, number];
77+
/** customized function used for generating request ID */
78+
generateID?: () => string;
4079

41-
export interface BindingContext {
42-
context: string;
43-
id: string;
80+
/** Declare the tag of specific xml document node. `TagPrefixKey` currently supports `encryptedAssertion` only */
81+
tagPrefix?: { encryptedAssertion?: string };
4482
}
4583

46-
export interface PostBindingContext extends BindingContext {
47-
relayState?: string;
48-
entityEndpoint: string;
49-
type: 'SAMLRequest' | 'SAMLResponse';
84+
export interface ParsedLogoutRequest {
85+
request?: { id?: string; issueInstant?: string; destination?: string };
86+
issuer?: string;
87+
nameID?: string;
88+
signature?: string;
5089
}
5190

52-
export interface ParseResult {
53-
samlContent: string;
54-
extract: any;
55-
sigAlg: string;
91+
export interface ParsedLogoutResponse {
92+
response?: { id?: string; destination?: string; inResponseTo?: string };
93+
issuer?: string;
94+
signature?: string;
5695
}
5796

5897
export class Entity<Settings extends EntitySettings = EntitySettings, Meta extends Metadata = Metadata> {
@@ -64,7 +103,7 @@ export class Entity<Settings extends EntitySettings = EntitySettings, Meta exten
64103
constructor(entitySettings: Settings, protected entityMeta: Meta) {
65104
// setting with metadata has higher precedence
66105
entitySettings.nameIDFormat = entityMeta.getNameIDFormat() || entitySettings.nameIDFormat;
67-
this.entitySettings = Object.assign({}, defaultEntitySetting, entitySettings);
106+
this.entitySettings = { ...defaultEntitySetting, ...entitySettings };
68107
}
69108
/**
70109
* @desc Returns the setting of entity

src/flow.ts

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
1-
import type { Entity, ESamlHttpRequest } from './entity';
1+
import type { ESamlHttpRequest } from './binding';
2+
import type { Entity } from './entity';
23
import { SamlifyError, SamlifyErrorCode } from './error';
34
import {
45
extract,
@@ -10,7 +11,7 @@ import {
1011
logoutResponseFields,
1112
logoutResponseStatusFields,
1213
} from './extractor';
13-
import libsaml from './libsaml';
14+
import { libsaml } from './libsaml';
1415
import { BindingNamespace, MessageSignatureOrder, ParserType, StatusCode, wording } from './urn';
1516
import { base64Decode, inflateString } from './utility';
1617
import { verifyTime } from './validator';

src/index.ts

Lines changed: 6 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,8 @@
11
export * from './api';
2-
export { default as identityProvider } from './entity-idp';
3-
export { default as serviceProvider } from './entity-sp';
4-
export * as extractor from './extractor';
5-
export { default as libsaml } from './libsaml';
6-
export { default as metadataIdp } from './metadata-idp';
7-
export { default as metadataSp } from './metadata-sp';
8-
export * from './types';
2+
export * from './entity-idp';
3+
export * from './entity-sp';
4+
export * from './error';
5+
export * from './libsaml';
6+
export * from './metadata-idp';
7+
export * from './metadata-sp';
98
export * from './urn';
10-
export * as utility from './utility';

0 commit comments

Comments
 (0)