@geexcode/geex-extensions-authentication 0.0.1

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.
@@ -0,0 +1,142 @@
1
+ import { signal, InjectionToken, makeEnvironmentProviders, importProvidersFrom } from '@angular/core';
2
+ import { gql, Apollo } from 'apollo-angular';
3
+ import { OAuthService, OAuthStorage, OAuthModule } from 'angular-oauth2-oidc';
4
+ import { firstValueFrom, map } from 'rxjs';
5
+ import { guardedSignal, GEEX_LOGIN_PATH, provideGeexModuleContribution } from '@geexcode/geex-angular';
6
+
7
+ const GQL_FEDERATE_AUTH = gql `mutation federateAuthenticate(
8
+ $code: String!
9
+ $loginProvider: LoginProviderEnum!
10
+ ) {
11
+ federateAuthenticate(
12
+ request: { code: $code, loginProvider: $loginProvider }
13
+ ) {
14
+ token
15
+ loginProvider
16
+ userId
17
+ name
18
+ user {
19
+ id
20
+ username
21
+ nickname
22
+ phoneNumber
23
+ email
24
+ isEnable
25
+ createdOn
26
+ ... on IUser {
27
+ roleNames
28
+ roleIds
29
+ permissions
30
+ orgCodes
31
+ avatarFileId
32
+ orgs {
33
+ allParentOrgs {
34
+ code
35
+ name
36
+ }
37
+ name
38
+ code
39
+ }
40
+ claims {
41
+ claimType
42
+ claimValue
43
+ }
44
+ avatarFile {
45
+ id
46
+ createdOn
47
+ fileSize
48
+ mimeType
49
+ storageType
50
+ fileName
51
+ md5
52
+ url
53
+ }
54
+ }
55
+ }
56
+ }
57
+ }
58
+ `;
59
+ function createAuthenticationModule(injector) {
60
+ const _user = signal(null, ...(ngDevMode ? [{ debugName: "_user" }] : []));
61
+ let _initialized = false;
62
+ let _initPromise = null;
63
+ const runInit = () => {
64
+ _initPromise = (async () => {
65
+ try {
66
+ const userData = await module.loadUserData();
67
+ _user.set(userData ?? null);
68
+ _initialized = true;
69
+ }
70
+ catch (err) {
71
+ console.error(err);
72
+ }
73
+ })();
74
+ return _initPromise;
75
+ };
76
+ const module = {
77
+ init: () => {
78
+ if (_initPromise) {
79
+ return _initPromise;
80
+ }
81
+ return runInit();
82
+ },
83
+ reload: () => {
84
+ _initialized = false;
85
+ _initPromise = null;
86
+ return runInit();
87
+ },
88
+ user: guardedSignal(_user, () => _initialized),
89
+ async loadUserData() {
90
+ const oAuthService = injector.get(OAuthService);
91
+ try {
92
+ // Always discover: issuer alignment is required for id_token / userinfo, not only endpoint URLs.
93
+ await oAuthService.loadDiscoveryDocument();
94
+ if (!oAuthService.hasValidAccessToken()) {
95
+ return undefined;
96
+ }
97
+ await oAuthService.loadUserProfile();
98
+ const profile = oAuthService.getIdentityClaims();
99
+ if (!profile?.login_provider) {
100
+ return undefined;
101
+ }
102
+ return await firstValueFrom(injector
103
+ .get(Apollo)
104
+ .mutate({
105
+ mutation: GQL_FEDERATE_AUTH,
106
+ variables: {
107
+ code: oAuthService.getAccessToken(),
108
+ loginProvider: profile.login_provider,
109
+ },
110
+ })
111
+ .pipe(map(res => res?.data?.federateAuthenticate.user)));
112
+ }
113
+ catch (err) {
114
+ console.error(err);
115
+ }
116
+ return undefined;
117
+ },
118
+ };
119
+ return module;
120
+ }
121
+
122
+ const GEEX_AUTHENTICATION_OPTIONS = new InjectionToken("GEEX_AUTHENTICATION_OPTIONS");
123
+ function provideGeexAuthentication(options = {}) {
124
+ return makeEnvironmentProviders([
125
+ { provide: GEEX_AUTHENTICATION_OPTIONS, useValue: options },
126
+ ...(options.loginPath ? [{ provide: GEEX_LOGIN_PATH, useValue: options.loginPath }] : []),
127
+ { provide: OAuthStorage, useFactory: options.oauthStorage ?? (() => localStorage) },
128
+ importProvidersFrom(OAuthModule.forRoot()),
129
+ provideGeexModuleContribution({
130
+ createModules: ({ injector }) => ({
131
+ authentication: (options.createAuthenticationModule ?? createAuthenticationModule)(injector),
132
+ }),
133
+ }),
134
+ ]);
135
+ }
136
+
137
+ /**
138
+ * Generated bundle index. Do not edit.
139
+ */
140
+
141
+ export { GEEX_AUTHENTICATION_OPTIONS, createAuthenticationModule, provideGeexAuthentication };
142
+ //# sourceMappingURL=geexcode-geex-extensions-authentication.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"geexcode-geex-extensions-authentication.mjs","sources":["../../src/authentication.module.ts","../../src/provide-geex-authentication.ts","../../src/geexcode-geex-extensions-authentication.ts"],"sourcesContent":["import { Injector, signal } from \"@angular/core\";\nimport { Apollo, gql } from \"apollo-angular\";\nimport { OAuthService } from \"angular-oauth2-oidc\";\nimport type { User } from \"@geexcode/geex-extensions-identity\";\nimport { firstValueFrom, map } from \"rxjs\";\nimport { guardedSignal } from \"@geexcode/geex-angular\";\nimport type { AuthenticationModule } from \"./authentication.types\";\n\nconst GQL_FEDERATE_AUTH = gql`mutation federateAuthenticate(\n $code: String!\n $loginProvider: LoginProviderEnum!\n) {\n federateAuthenticate(\n request: { code: $code, loginProvider: $loginProvider }\n ) {\n token\n loginProvider\n userId\n name\n user {\n id\n username\n nickname\n phoneNumber\n email\n isEnable\n createdOn\n ... on IUser {\n roleNames\n roleIds\n permissions\n orgCodes\n avatarFileId\n orgs {\n allParentOrgs {\n code\n name\n }\n name\n code\n }\n claims {\n claimType\n claimValue\n }\n avatarFile {\n id\n createdOn\n fileSize\n mimeType\n storageType\n fileName\n md5\n url\n }\n }\n }\n }\n}\n`;\n\nexport function createAuthenticationModule(injector: Injector): AuthenticationModule {\n const _user = signal<User | null>(null);\n let _initialized = false;\n let _initPromise: Promise<void> | null = null;\n\n const runInit = () => {\n _initPromise = (async () => {\n try {\n const userData = await module.loadUserData();\n _user.set(userData ?? null);\n _initialized = true;\n } catch (err) {\n console.error(err);\n }\n })();\n return _initPromise;\n };\n\n const module = {\n init: () => {\n if (_initPromise) {\n return _initPromise;\n }\n return runInit();\n },\n reload: () => {\n _initialized = false;\n _initPromise = null;\n return runInit();\n },\n user: guardedSignal(_user, () => _initialized),\n async loadUserData(): Promise<User | undefined> {\n const oAuthService = injector.get(OAuthService);\n try {\n // Always discover: issuer alignment is required for id_token / userinfo, not only endpoint URLs.\n await oAuthService.loadDiscoveryDocument();\n if (!oAuthService.hasValidAccessToken()) {\n return undefined;\n }\n await oAuthService.loadUserProfile();\n const profile = oAuthService.getIdentityClaims() as { login_provider?: string } | null;\n if (!profile?.login_provider) {\n return undefined;\n }\n type FederateAuthResponse = { federateAuthenticate: { user: User } };\n return await firstValueFrom(\n injector\n .get(Apollo)\n .mutate<FederateAuthResponse>({\n mutation: GQL_FEDERATE_AUTH,\n variables: {\n code: oAuthService.getAccessToken(),\n loginProvider: profile.login_provider,\n },\n })\n .pipe(map(res => res?.data?.federateAuthenticate.user)),\n );\n } catch (err) {\n console.error(err);\n }\n return undefined;\n },\n };\n return module as AuthenticationModule;\n}\n","import {\r\r\n EnvironmentProviders,\r\r\n InjectionToken,\r\r\n Injector,\r\r\n importProvidersFrom,\r\r\n makeEnvironmentProviders,\r\r\n} from \"@angular/core\";\r\r\nimport { GEEX_LOGIN_PATH, provideGeexModuleContribution } from \"@geexcode/geex-angular\";\r\r\nimport { OAuthModule, OAuthStorage } from \"angular-oauth2-oidc\";\r\r\nimport { createAuthenticationModule } from \"./authentication.module\";\r\r\nimport type { AuthenticationModule } from \"./authentication.types\";\r\r\n\r\r\nexport interface GeexAuthenticationOptions {\r\r\n readonly createAuthenticationModule?: (injector: Injector) => AuthenticationModule;\r\r\n readonly loginPath?: string;\r\r\n readonly oauthStorage?: () => OAuthStorage;\r\r\n}\r\r\n\r\r\nexport const GEEX_AUTHENTICATION_OPTIONS = new InjectionToken<Readonly<GeexAuthenticationOptions>>(\r\r\n \"GEEX_AUTHENTICATION_OPTIONS\",\r\r\n);\r\r\n\r\r\nexport function provideGeexAuthentication(\r\r\n options: Readonly<GeexAuthenticationOptions> = {},\r\r\n): EnvironmentProviders {\r\r\n return makeEnvironmentProviders([\r\r\n { provide: GEEX_AUTHENTICATION_OPTIONS, useValue: options },\r\r\n ...(options.loginPath ? [{ provide: GEEX_LOGIN_PATH, useValue: options.loginPath }] : []),\r\r\n { provide: OAuthStorage, useFactory: options.oauthStorage ?? (() => localStorage) },\r\r\n importProvidersFrom(OAuthModule.forRoot()),\r\r\n provideGeexModuleContribution({\r\r\n createModules: ({ injector }) => ({\r\r\n authentication: (options.createAuthenticationModule ?? createAuthenticationModule)(injector),\r\r\n }),\r\r\n }),\r\r\n ]);\r\r\n}\r\r\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './public-api';\n"],"names":[],"mappings":"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"}
@@ -0,0 +1,31 @@
1
+ import { WritableSignal, Injector, InjectionToken, EnvironmentProviders } from '@angular/core';
2
+ import { GeexModule } from '@geexcode/geex-angular';
3
+ import { User } from '@geexcode/geex-extensions-identity';
4
+ import { OAuthStorage } from 'angular-oauth2-oidc';
5
+
6
+ interface AuthenticationModule extends GeexModule<{
7
+ user: WritableSignal<User | null>;
8
+ loadUserData(): Promise<User | undefined>;
9
+ /** Drop cached session and reload user from the current OAuth access token. */
10
+ reload(): Promise<void>;
11
+ }> {
12
+ }
13
+ declare module "@geexcode/geex-angular" {
14
+ interface GeexModuleMap {
15
+ authentication: AuthenticationModule;
16
+ }
17
+ }
18
+
19
+ declare function createAuthenticationModule(injector: Injector): AuthenticationModule;
20
+
21
+ interface GeexAuthenticationOptions {
22
+ readonly createAuthenticationModule?: (injector: Injector) => AuthenticationModule;
23
+ readonly loginPath?: string;
24
+ readonly oauthStorage?: () => OAuthStorage;
25
+ }
26
+ declare const GEEX_AUTHENTICATION_OPTIONS: InjectionToken<Readonly<GeexAuthenticationOptions>>;
27
+ declare function provideGeexAuthentication(options?: Readonly<GeexAuthenticationOptions>): EnvironmentProviders;
28
+
29
+ export { GEEX_AUTHENTICATION_OPTIONS, createAuthenticationModule, provideGeexAuthentication };
30
+ export type { AuthenticationModule, GeexAuthenticationOptions };
31
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sources":["../src/authentication.types.ts","../src/authentication.module.ts","../src/provide-geex-authentication.ts"],"mappings":";;;;;AAIA,UAAM,oBAAW,SAAqB,UAAQ;AAC5C,UAAM,cAAc,CAAC,IAAI;AACzB,oBAAgB,OAAO,CAAC,IAAI;;AAE5B,cAAU,OAAO;;AACd;AAEL;AACE;wBACkB,oBAAoB;AACrC;AACF;;AC8CD,iBAAA,qCAA2C,QAAU,GAAA;;ACrCrD,mCAAiB;qDAEkC,QAAQ,KAAK,oBAAoB;AAElF;AAEA,kCAA8B,YAAY;AAE3C;AAID,cAAA,2BAAa,EAAA,cAA2B,CAAA,QAAA,CAAA,yBAAA;AAQxC,iBAAA,yBAAgB,WAEd,QAAS,CAAA,yBAAS,IAAA,oBAEjB;;;;","names":[]}
package/package.json ADDED
@@ -0,0 +1,54 @@
1
+ {
2
+ "name": "@geexcode/geex-extensions-authentication",
3
+ "version": "0.0.1",
4
+ "description": "Geex authentication extension: headless OAuth authentication module and domain tokens. Aligns with Geex.Extensions.Authentication.",
5
+ "sideEffects": false,
6
+ "peerDependencies": {
7
+ "@angular/core": "^20.0.0",
8
+ "@geexcode/geex-angular": ">=0.0.41",
9
+ "@geexcode/geex-extensions-identity": ">=0.0.1",
10
+ "angular-oauth2-oidc": ">=15.0.0 <21.0.0",
11
+ "apollo-angular": "^14.0.0",
12
+ "graphql": "^16.8.0",
13
+ "rxjs": "^7.8.0"
14
+ },
15
+ "dependencies": {
16
+ "tslib": "^2.6.3"
17
+ },
18
+ "files": [
19
+ "dist"
20
+ ],
21
+ "module": "dist/fesm2022/geexcode-geex-extensions-authentication.mjs",
22
+ "typings": "dist/index.d.ts",
23
+ "exports": {
24
+ "./package.json": {
25
+ "default": "./package.json"
26
+ },
27
+ ".": {
28
+ "types": "./dist/index.d.ts",
29
+ "import": "./dist/fesm2022/geexcode-geex-extensions-authentication.mjs",
30
+ "default": "./dist/fesm2022/geexcode-geex-extensions-authentication.mjs"
31
+ }
32
+ },
33
+ "scripts": {
34
+ "clean": "rimraf dist",
35
+ "build": "ng-packagr -p ng-package.json -c tsconfig.lib.json",
36
+ "test": "node --test src/provide-geex-authentication.node-test.mjs",
37
+ "prepublishOnly": "npm run build",
38
+ "publish:public": "npm publish ./dist --access public"
39
+ },
40
+ "devDependencies": {
41
+ "@angular/compiler": "^20.0.0",
42
+ "@angular/compiler-cli": "^20.0.0",
43
+ "@angular/core": "^20.0.0",
44
+ "@geexcode/geex-angular": "workspace:*",
45
+ "@geexcode/geex-extensions-identity": "workspace:*",
46
+ "angular-oauth2-oidc": "^20.0.2",
47
+ "apollo-angular": "^14.1.0",
48
+ "graphql": "^16.9.0",
49
+ "ng-packagr": "^20.0.0",
50
+ "rimraf": "^5.0.5",
51
+ "rxjs": "^7.8.2",
52
+ "typescript": "~5.8.3"
53
+ }
54
+ }