@owlmeans/server-auth 0.1.18-rc.2 → 0.1.18-rc.21

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.
Files changed (96) hide show
  1. package/README.md +11 -5
  2. package/agent-meta/manifest.json +9 -2
  3. package/agent-meta/skills/server-auth/SKILL.md +93 -22
  4. package/agent-meta/skills/supervisor-auth/SKILL.md +128 -0
  5. package/build/actions/service.d.ts +6 -2
  6. package/build/actions/service.d.ts.map +1 -1
  7. package/build/actions/service.js +5 -4
  8. package/build/actions/service.js.map +1 -1
  9. package/build/entrypoints.d.ts +5 -0
  10. package/build/entrypoints.d.ts.map +1 -0
  11. package/build/entrypoints.js +9 -0
  12. package/build/entrypoints.js.map +1 -0
  13. package/build/index.d.ts +1 -1
  14. package/build/index.d.ts.map +1 -1
  15. package/build/index.js +1 -1
  16. package/build/index.js.map +1 -1
  17. package/build/manager/actions/manager.d.ts +17 -5
  18. package/build/manager/actions/manager.d.ts.map +1 -1
  19. package/build/manager/actions/manager.js +7 -6
  20. package/build/manager/actions/manager.js.map +1 -1
  21. package/build/manager/context.d.ts.map +1 -1
  22. package/build/manager/context.js +0 -1
  23. package/build/manager/context.js.map +1 -1
  24. package/build/manager/entrypoints.d.ts +9 -0
  25. package/build/manager/entrypoints.d.ts.map +1 -0
  26. package/build/manager/entrypoints.js +24 -0
  27. package/build/manager/entrypoints.js.map +1 -0
  28. package/build/manager/exports.d.ts +1 -2
  29. package/build/manager/exports.d.ts.map +1 -1
  30. package/build/manager/exports.js +1 -2
  31. package/build/manager/exports.js.map +1 -1
  32. package/build/manager/index.d.ts +1 -1
  33. package/build/manager/index.d.ts.map +1 -1
  34. package/build/manager/index.js +1 -1
  35. package/build/manager/index.js.map +1 -1
  36. package/build/manager/main.js +2 -2
  37. package/build/manager/main.js.map +1 -1
  38. package/build/manager/model.d.ts.map +1 -1
  39. package/build/manager/model.js +14 -1
  40. package/build/manager/model.js.map +1 -1
  41. package/build/manager/plugins/basic-ed25519.js.map +1 -1
  42. package/build/manager/plugins/basic-rely.d.ts.map +1 -1
  43. package/build/manager/plugins/basic-rely.js +5 -5
  44. package/build/manager/plugins/basic-rely.js.map +1 -1
  45. package/build/manager/plugins/re-captcha.js +1 -1
  46. package/build/manager/plugins/re-captcha.js.map +1 -1
  47. package/build/manager/plugins/supervisor.js +3 -3
  48. package/build/manager/plugins/supervisor.js.map +1 -1
  49. package/build/manager/rely/flow.js +1 -1
  50. package/build/manager/rely/flow.js.map +1 -1
  51. package/build/manager/supervisor.d.ts +5 -5
  52. package/build/manager/supervisor.d.ts.map +1 -1
  53. package/build/manager/supervisor.js +4 -4
  54. package/build/manager/supervisor.js.map +1 -1
  55. package/build/model/rely/consumer.d.ts +3 -1
  56. package/build/model/rely/consumer.d.ts.map +1 -1
  57. package/build/model/rely/consumer.js.map +1 -1
  58. package/build/model/rely/provider.d.ts +3 -1
  59. package/build/model/rely/provider.d.ts.map +1 -1
  60. package/build/model/rely/provider.js.map +1 -1
  61. package/build/service.js +1 -1
  62. package/build/service.js.map +1 -1
  63. package/package.json +26 -26
  64. package/src/actions/service.ts +9 -8
  65. package/src/entrypoints.ts +12 -0
  66. package/src/index.ts +1 -1
  67. package/src/manager/README.md +14 -18
  68. package/src/manager/actions/manager.ts +15 -13
  69. package/src/manager/context.ts +0 -2
  70. package/src/manager/entrypoints.ts +26 -0
  71. package/src/manager/exports.ts +1 -2
  72. package/src/manager/index.ts +1 -1
  73. package/src/manager/main.ts +2 -2
  74. package/src/manager/model.ts +16 -1
  75. package/src/manager/plugins/basic-ed25519.ts +2 -2
  76. package/src/manager/plugins/basic-rely.ts +7 -6
  77. package/src/manager/plugins/re-captcha.ts +3 -3
  78. package/src/manager/plugins/supervisor.ts +4 -4
  79. package/src/manager/rely/flow.ts +1 -1
  80. package/src/manager/supervisor.ts +6 -6
  81. package/src/model/rely/consumer.ts +3 -1
  82. package/src/model/rely/provider.ts +3 -1
  83. package/src/service.ts +1 -1
  84. package/tests/context.ts +1 -2
  85. package/tests/supervisor.spec.ts +6 -4
  86. package/build/.gitkeep +0 -0
  87. package/build/manager/modules.d.ts +0 -2
  88. package/build/manager/modules.d.ts.map +0 -1
  89. package/build/manager/modules.js +0 -21
  90. package/build/manager/modules.js.map +0 -1
  91. package/build/modules.d.ts +0 -3
  92. package/build/modules.d.ts.map +0 -1
  93. package/build/modules.js +0 -11
  94. package/build/modules.js.map +0 -1
  95. package/src/manager/modules.ts +0 -29
  96. package/src/modules.ts +0 -17
@@ -27,18 +27,18 @@ A specialized guard service that enables authentication token relay between micr
27
27
  - **Wallet DID Authentication**: Decentralized identity authentication support
28
28
  - **Challenge Validation**: Anti-replay protection using challenge-response mechanisms
29
29
 
30
- ### Module-Based Architecture
31
- The manager is built on the OwlMeans module system, providing:
30
+ ### Entrypoint-Based Architecture
31
+ The manager is built on the OwlMeans entrypoint system, providing:
32
32
  - **Route Management**: Standardized API endpoints for authentication operations
33
- - **Handler Registration**: Modular request handlers for different authentication flows
34
- - **Guard Integration**: Automatic security enforcement at the module level
33
+ - **Handler Registration**: Protocol-backed request handlers for different authentication flows
34
+ - **Guard Integration**: Automatic security enforcement at the entrypoint level
35
35
 
36
36
  ## Installation
37
37
 
38
38
  This manager app is part of the `@owlmeans/server-auth` package:
39
39
 
40
40
  ```bash
41
- npm install @owlmeans/server-auth
41
+ npm install @owlmeans/server-auth@^0.1.18-rc.17
42
42
  ```
43
43
 
44
44
  ## API Reference
@@ -317,20 +317,16 @@ await authModel.rely(connection, authToken.auth)
317
317
 
318
318
  ### API Integration
319
319
 
320
- ```typescript
321
- import { modules } from '@owlmeans/server-auth/manager'
322
-
323
- // The manager automatically registers these API endpoints:
320
+ `main(context)` registers the manager's immutable `entrypoints` and starts the API server. For a
321
+ custom bootstrap, register the exported collection yourself; the manager's protocols are then
322
+ addressed through the same `context.entrypoint(protocol)` lookup as application endpoints.
324
323
 
325
- // POST /api/auth/init - Authentication initialization
326
- // POST /api/auth/authenticate - User authentication
327
- // WebSocket /api/auth/rely - Authentication relay
324
+ ```typescript
325
+ import { entrypoints, makeContext } from '@owlmeans/server-auth/manager'
328
326
 
329
- // Access modules for custom routing
330
- modules.forEach(module => {
331
- console.log(`Route: ${module.getPath()}`)
332
- console.log(`Method: ${module.route.method}`)
333
- })
327
+ const context = makeContext(config)
328
+ context.registerEntrypoints(entrypoints)
329
+ await context.configure().init()
334
330
  ```
335
331
 
336
332
  ## API Endpoints
@@ -504,4 +500,4 @@ This manager app depends on:
504
500
  - [`@owlmeans/server-auth`](../../../README.md) - Parent server authentication package
505
501
  - [`@owlmeans/auth`](../../../auth/README.md) - Core authentication library
506
502
  - [`@owlmeans/client-auth`](../../../client-auth/README.md) - Client-side authentication
507
- - [`@owlmeans/context`](../../../context/README.md) - Context management system
503
+ - [`@owlmeans/context`](../../../context/README.md) - Context management system
@@ -1,23 +1,25 @@
1
- import type { AllowanceRequest, AuthCredentials } from '@owlmeans/auth'
2
- import { handleBody } from '@owlmeans/server-api'
1
+ import type { AllowanceRequest, AllowanceResponse, AuthCredentials, AuthToken } from '@owlmeans/auth'
2
+ import type { EntrypointProtocol } from '@owlmeans/entrypoint'
3
+ import { handlers } from '@owlmeans/server-api'
3
4
  import { makeAuthModel } from '../model.js'
4
- import type { RefedEntrypointHandler } from '@owlmeans/server-entrypoint'
5
5
  import type { AppContext, AppConfig } from '../types.js'
6
- import { handleConnection } from '@owlmeans/server-socket'
6
+ import { connection } from '@owlmeans/server-socket'
7
7
 
8
- export const authenticationInit: RefedEntrypointHandler<AllowanceRequest> = handleBody(
9
- async (payload: AllowanceRequest, ctx) =>
10
- await makeAuthModel(ctx as AppContext<AppConfig>).init(payload)
8
+ const api = handlers<AppContext<AppConfig>>()
9
+
10
+ export const authenticationInit = (protocol: EntrypointProtocol<{ body: AllowanceRequest }, AllowanceResponse>) =>
11
+ api.body(protocol, async (body, context) =>
12
+ await makeAuthModel(context).init(body)
11
13
  )
12
14
 
13
- export const authenticate: RefedEntrypointHandler<AuthCredentials> = handleBody(
14
- async (payload: AuthCredentials, ctx) =>
15
- await makeAuthModel(ctx as AppContext<AppConfig>).authenticate(payload)
15
+ export const authenticate = (protocol: EntrypointProtocol<{ body: AuthCredentials }, AuthToken>) =>
16
+ api.body(protocol, async (body, context) =>
17
+ await makeAuthModel(context).authenticate(body)
16
18
  )
17
19
 
18
- export const rely: RefedEntrypointHandler<void> = handleConnection(
20
+ export const rely = (protocol: EntrypointProtocol<{ query: Partial<AuthToken> }, undefined>) => connection(protocol,
19
21
  // @TODO Request will contain information is there requrest
20
22
  // privileged or not (privileged request implies auth provider)
21
- async (conn, ctx, req) =>
22
- await makeAuthModel(ctx as AppContext<AppConfig>).rely(conn, req.auth)
23
+ async (conn, context, request) =>
24
+ await makeAuthModel(context as AppContext<AppConfig>).rely(conn, request.auth)
23
25
  )
@@ -27,7 +27,5 @@ export const makeContext = <C extends AppConfig, T extends AppContext<C>>(cfg: C
27
27
  appendStaticResource<C, T>(context, AUTH_CACHE)
28
28
  }
29
29
 
30
- context.makeContext = (cfg => makeContext(cfg, customize)) as typeof context.makeContext
31
-
32
30
  return context as T
33
31
  }
@@ -0,0 +1,26 @@
1
+
2
+ import { MOD_RECAPTCHA } from '@owlmeans/auth'
3
+ import { authProtocols } from '@owlmeans/auth-common'
4
+ import { entrypoints as apiConfigBindings } from '@owlmeans/api-config-server'
5
+ import { bind } from '@owlmeans/server-entrypoint'
6
+ import { decorateEntrypoint, openProtocol } from '@owlmeans/entrypoint'
7
+ import * as actions from './actions/index.js'
8
+ import { backend, route, RouteMethod } from '@owlmeans/route'
9
+ import { DEFAULT_RELY } from './consts.js'
10
+
11
+ const relyProtocol = decorateEntrypoint(authProtocols.rely, { guards: DEFAULT_RELY })
12
+ const reCaptchaProtocol = openProtocol(route(MOD_RECAPTCHA, '/api/siteverify', backend({
13
+ host: 'https://www.google.com',
14
+ base: 'recaptcha',
15
+ secure: true,
16
+ }, RouteMethod.POST)))
17
+
18
+ /** Server entrypoints for the full authentication manager. */
19
+ export const entrypoints = [
20
+ bind(authProtocols.authen, undefined, { intermediate: true }),
21
+ bind(authProtocols.init, actions.authenticationInit(authProtocols.init)),
22
+ bind(authProtocols.authenticate, actions.authenticate(authProtocols.authenticate)),
23
+ bind(relyProtocol, actions.rely(relyProtocol)),
24
+ ...apiConfigBindings,
25
+ bind(reCaptchaProtocol),
26
+ ]
@@ -5,8 +5,7 @@ export { addWebService } from '@owlmeans/client-config'
5
5
  export { service, TRUSTED } from '@owlmeans/config'
6
6
  export { AppType, assertContext } from '@owlmeans/context'
7
7
  export { klusterize } from '@owlmeans/kluster'
8
- export { elevate } from '@owlmeans/server-entrypoint'
9
- export { elevate as celevate, stab } from '@owlmeans/client-entrypoint'
8
+ export { stab } from '@owlmeans/client-entrypoint'
10
9
  export type { RefedEntrypointHandler } from '@owlmeans/server-entrypoint'
11
10
  export { handleIntermediate, handleBody, handleRequest, handleParams } from '@owlmeans/server-api'
12
11
  export type { AbstractRequest, AbstractResponse } from '@owlmeans/entrypoint'
@@ -1,6 +1,6 @@
1
1
  export type * from './types.js'
2
2
 
3
- export * from './modules.js'
3
+ export * from './entrypoints.js'
4
4
  export * from './exports.js'
5
5
  export * from './context.js'
6
6
  export * from './main.js'
@@ -1,9 +1,9 @@
1
1
 
2
- import { modules } from './modules.js'
2
+ import { entrypoints } from './entrypoints.js'
3
3
  import type { AppContext, AppConfig } from './types.js'
4
4
 
5
5
  export const main = async <C extends AppConfig, T extends AppContext<C>>(ctx: T) => {
6
- ctx.registerEntrypoints(modules)
6
+ ctx.registerEntrypoints(entrypoints)
7
7
  await ctx.configure().init()
8
8
  await ctx.getApiServer().listen()
9
9
  }
@@ -1,6 +1,8 @@
1
1
  import type { AuthModel, AppConfig, AppContext } from './types.js'
2
- import { AuthenFailed, AuthenPayloadError } from '@owlmeans/auth'
2
+ import { AuthenFailed, AuthenPayloadError, entitySlugOf } from '@owlmeans/auth'
3
3
  import type { AuthCredentials } from '@owlmeans/auth'
4
+ import type { EntityResolverService } from '@owlmeans/auth-common'
5
+ import { ENTITY_RESOLVER } from '@owlmeans/auth-common'
4
6
  import { getPlugin } from './plugins/utils.js'
5
7
  import { AUTH_CACHE, AUTHEN_TIMEFRAME } from '../consts.js'
6
8
  import { EnvelopeKind, makeEnvelopeModel } from '@owlmeans/basic-envelope'
@@ -75,6 +77,19 @@ export const makeAuthModel = (context: AppContext<AppConfig>): AuthModel => {
75
77
  const { token } = await plugin.authenticate(Object.assign(credential, { challenge: msg }))
76
78
  credential.challenge = token === '' ? challenge : token
77
79
 
80
+ // Plugins accept whatever the caller typed — a current slug, a slug the organization has
81
+ // since retired, or (for a token minted before slugs existed) its stable key. The token is
82
+ // signed once and read for as long as it lives, so the value is canonicalized here rather
83
+ // than at every place that later reads it back.
84
+ const entitySlug = entitySlugOf(credential)
85
+ if (entitySlug != null && context.hasService(ENTITY_RESOLVER)) {
86
+ const entity = await context.service<EntityResolverService>(ENTITY_RESOLVER).resolve(entitySlug)
87
+ if (entity == null) {
88
+ throw new AuthenFailed('entity')
89
+ }
90
+ credential.entitySlug = entity.slug
91
+ }
92
+
78
93
  credential.credential = trustedUser.id
79
94
 
80
95
  return {
@@ -23,8 +23,8 @@ export const basicEd25519 = <C extends AppConfig, T extends AppContext<C>>(conte
23
23
  /**
24
24
  * @TODO We need to find users in some db not just in static
25
25
  */
26
- const systemUser = await context.getConfigResource(TRUSTED)
27
- .load<TrustedRecord>(credential.userId)
26
+ const systemUser = await context.getConfigResource<TrustedRecord>(TRUSTED)
27
+ .load(credential.userId)
28
28
 
29
29
  if (systemUser == null) {
30
30
  throw new AuthenFailed()
@@ -7,17 +7,18 @@ import { trusted } from '../utils/trusted.js'
7
7
  import { EnvelopeKind, makeEnvelopeModel } from '@owlmeans/basic-envelope'
8
8
  import { AUTH_CACHE } from '../../consts.js'
9
9
  import { ResourceError } from '@owlmeans/resource'
10
+ import type { Unsubscribe } from '@owlmeans/resource'
10
11
  import { RELY_CALL_TIMEOUT, RELY_PIN_PERFIX, RELY_TOKEN_PREFIX } from '@owlmeans/auth-common'
11
12
 
12
- const _subscriptions: Record<string, CallableFunction> = {}
13
+ const _subscriptions: Record<string, Unsubscribe> = {}
13
14
  export const basicRely = (context: AppContext, type?: string): AuthPlugin => {
14
15
  const plugin: AuthPlugin = {
15
16
  type: type ?? AuthenticationType.RelyHandshake,
16
17
 
17
18
  // This method is used by consumer and by provider (wallet)
18
19
  // to initialize shared authentication process.
19
- // The idea is that both subscribe to wait for a handshake value
20
- // from the peer, that in fact is a subscription to a redis message tunnel.
20
+ // The idea is that both watch the record holding their own pin/token and wake
21
+ // up when the peer writes its handshake value into it.
21
22
  init: async (request: RelyAllowanceRequest): Promise<AllowanceResponse> => {
22
23
  const [, keyPair] = await trusted(context)
23
24
  const tunnel = context.resource<AuthRedisResource>(AUTH_CACHE)
@@ -41,8 +42,8 @@ export const basicRely = (context: AppContext, type?: string): AuthPlugin => {
41
42
 
42
43
  if (request.provideRely != null) {
43
44
  await Promise.all([pin, token].filter(key => key != null).map(async key => {
44
- _subscriptions[key] = await tunnel.subscribe(async value => {
45
- if (value.challenge != null) {
45
+ _subscriptions[key] = await tunnel.watch(key, async value => {
46
+ if (value?.challenge != null) {
46
47
  const rely = makeEnvelopeModel<RelyToken>(value.challenge, EnvelopeKind.Wrap)
47
48
  if (await rely.verify(keyPair)) {
48
49
  [pin, token].filter(key => key != null).forEach(key => {
@@ -54,7 +55,7 @@ export const basicRely = (context: AppContext, type?: string): AuthPlugin => {
54
55
  await request.provideRely?.(rely.message(), relyMsg, true)
55
56
  }
56
57
  }
57
- }, { /*ttl: RELY_CALL_TIMEOUT,*/ key, once: true })
58
+ }, { once: true })
58
59
 
59
60
  // @TODO they need to be killed on close - but actually live a little bit longer
60
61
  // then timeout for them is ok
@@ -23,13 +23,13 @@ export const reCaptcha = <C extends AppConfig, T extends AppContext<C>>(context:
23
23
  },
24
24
 
25
25
  authenticate: async credential => {
26
- const cfg = context.getConfigResource(PLUGINS)
27
- const config = await cfg.get<PluginConfig>(MOD_RECAPTCHA)
26
+ const cfg = context.getConfigResource<PluginConfig>(PLUGINS)
27
+ const config = await cfg.get(MOD_RECAPTCHA)
28
28
  if (config.value == null) {
29
29
  throw new PluginMissconfigured('value')
30
30
  }
31
31
  const validateRecaptcha = context.entrypoint<ClientEntrypoint<RecpatchaResponse>>(MOD_RECAPTCHA)
32
- const [result, status] = await validateRecaptcha.call<RecpatchaResponse, RecaptchaRequest>({
32
+ const { value: result, outcome: status } = await validateRecaptcha.invoke<RecpatchaResponse, RecaptchaRequest>({
33
33
  body: {
34
34
  secret: config.value,
35
35
  response: credential.credential
@@ -48,8 +48,8 @@ export const makeSupervisorPlugin = (
48
48
  let matched: string | null = null
49
49
  for (const alias of opts.supervisors) {
50
50
  try {
51
- const record = await context.getConfigResource(TRUSTED)
52
- .load<TrustedRecord>(alias, 'name')
51
+ const record = await context.getConfigResource<TrustedRecord>(TRUSTED)
52
+ .load({ name: alias })
53
53
  if (record?.credential == null) {
54
54
  continue
55
55
  }
@@ -71,8 +71,8 @@ export const makeSupervisorPlugin = (
71
71
 
72
72
  credential.userId = resolution.userId
73
73
  credential.profileId = resolution.profileId ?? resolution.userId
74
- if (resolution.entityId != null) {
75
- credential.entityId = resolution.entityId
74
+ if (resolution.entitySlug != null) {
75
+ credential.entitySlug = resolution.entitySlug
76
76
  }
77
77
  credential.scopes = resolution.scopes ?? credential.scopes ?? [ALL_SCOPES]
78
78
  credential.role = resolution.role ?? AuthRole.User
@@ -38,7 +38,7 @@ export const createRelyFlow = (context: AppContext, conn: Connection, auth?: Aut
38
38
  await closeReceiver()
39
39
  }
40
40
  }
41
- }, source.nonce)
41
+ }, { channel: source.nonce })
42
42
  // We allow to just forward call messages back and forth
43
43
  conn._receiveCall = async msg => { console.info(source.nonce, 'Forward call', msg.method, msg.id) }
44
44
  conn._receiveResult = async msg => { console.info(source.nonce, 'Forward result', msg.id) }
@@ -10,7 +10,7 @@ import { makeSupervisorPlugin } from './plugins/supervisor.js'
10
10
  * token will represent. Only `userId` is required - the rest default sensibly.
11
11
  */
12
12
  export interface SupervisorUserResolution extends Partial<Pick<AuthPayload,
13
- 'profileId' | 'entityId' | 'role' | 'scopes'>> {
13
+ 'profileId' | 'entitySlug' | 'role' | 'scopes'>> {
14
14
  userId: string
15
15
  }
16
16
 
@@ -43,7 +43,7 @@ export interface SupervisorAuthOptions {
43
43
  enabled?: boolean
44
44
  /**
45
45
  * Also accept internal owlmeans `Ed25519BasicToken`s even when another guard
46
- * (e.g. OIDC) is the primary guard on protected modules. Default: true.
46
+ * (e.g. OIDC) is the primary guard on protected entrypoints. Default: true.
47
47
  */
48
48
  acceptInternalTokens?: boolean
49
49
  /** The internal-token guard to add as a coguard. Default: DEFAULT_GUARD ('auth'). */
@@ -57,15 +57,15 @@ const isDevelopment = (context: { cfg: { debug?: { all?: boolean, supervisor?: b
57
57
 
58
58
  /**
59
59
  * Ensure the internal `Ed25519BasicToken` guard is accepted as a coguard on every
60
- * already-guarded backend module, so internal owlmeans tokens keep working even
60
+ * already-guarded backend entrypoint, so internal owlmeans tokens keep working even
61
61
  * when another guard (e.g. OIDC) is the primary guard. The primary guard stays
62
62
  * first; the internal guard is appended as a fallback (its `match` only fires for
63
63
  * an `Ed25519BasicToken` authorization header).
64
64
  */
65
65
  export const setupInternalTokenCoguard = (
66
- modules: Array<{ guards?: string[] }>, guard: string = DEFAULT_GUARD
66
+ entrypoints: Array<{ guards?: string[] }>, guard: string = DEFAULT_GUARD
67
67
  ): void => {
68
- modules.forEach(module => {
68
+ entrypoints.forEach(module => {
69
69
  if (module.guards != null && module.guards.length > 0 && !module.guards.includes(guard)) {
70
70
  module.guards.push(guard)
71
71
  }
@@ -78,7 +78,7 @@ export const setupInternalTokenCoguard = (
78
78
  *
79
79
  * It registers the supervisor auth plugin (verifies a front-end signature against
80
80
  * the allowlisted trusted keys, then resolves/registers the target user) and -
81
- * unless disabled - makes protected modules also accept internal owlmeans tokens
81
+ * unless disabled - makes protected entrypoints also accept internal owlmeans tokens
82
82
  * (requirement: understand internal tokens even when OIDC is the primary guard).
83
83
  */
84
84
  export const appendSupervisorAuth = <C extends AppConfig, T extends AppContext<C>>(
@@ -1,7 +1,9 @@
1
1
  import { makeRelyModel } from './peer.js'
2
+ import type { RelyToken } from '@owlmeans/auth'
3
+ import type { EnvelopeModel } from '@owlmeans/basic-envelope'
2
4
  import type { RelyOptions } from './types.js'
3
5
 
4
- export const makeConsumerRely = (opts?: RelyOptions) => {
6
+ export const makeConsumerRely = (opts?: RelyOptions): EnvelopeModel<RelyToken> => {
5
7
  const model = makeRelyModel(opts)
6
8
  const msg = model.message()
7
9
  delete msg.pin
@@ -1,8 +1,10 @@
1
1
 
2
2
  import { makeRelyModel } from './peer.js'
3
+ import type { RelyToken } from '@owlmeans/auth'
4
+ import type { EnvelopeModel } from '@owlmeans/basic-envelope'
3
5
  import type { RelyOptions } from './types.js'
4
6
 
5
- export const makeProviderRely = (opts?: RelyOptions) => {
7
+ export const makeProviderRely = (opts?: RelyOptions): EnvelopeModel<RelyToken> => {
6
8
  const model = makeRelyModel(opts)
7
9
 
8
10
  return model
package/src/service.ts CHANGED
@@ -92,7 +92,7 @@ export const makeAuthService = (alias: string = DEFAULT_ALIAS): AuthService => {
92
92
  type: AuthroizationType.Ed25519BasicToken,
93
93
  source: context.cfg.service,
94
94
  profileId: credentials.profileId,
95
- entityId: credentials.entityId,
95
+ entitySlug: credentials.entitySlug,
96
96
  isUser: true,
97
97
  createdAt: new Date()
98
98
  }
package/tests/context.ts CHANGED
@@ -1,4 +1,4 @@
1
- import { AppType, Layer, makeBasicContext } from '@owlmeans/context'
1
+ import { AppType, makeBasicContext } from '@owlmeans/context'
2
2
  import type { BasicConfig, BasicContext } from '@owlmeans/context'
3
3
  import { createStaticResource } from '@owlmeans/static-resource'
4
4
  import { makeMemoryTrustedResource, makeFixtureKeyPair } from '@owlmeans/test-auth'
@@ -39,7 +39,6 @@ export const makeTestContext = () => {
39
39
  const cfg: BasicConfig = {
40
40
  ready: false,
41
41
  service: SERVICE_NAME,
42
- layer: Layer.Service,
43
42
  type: AppType.Backend,
44
43
  services: {},
45
44
  }
@@ -3,6 +3,8 @@ import { makeFixtureKeyPair } from '@owlmeans/test-auth'
3
3
  import { AuthenticationType, AuthRole, buildSupervisorPayload } from '@owlmeans/auth'
4
4
  import type { AuthCredentials } from '@owlmeans/auth'
5
5
  import type { TrustedRecord } from '@owlmeans/auth-common'
6
+ import type { Criteria } from '@owlmeans/resource'
7
+ import { firstMatch } from '@owlmeans/resource'
6
8
  import { makeSupervisorPlugin } from '../src/manager/plugins/supervisor.js'
7
9
  import type { AppConfig, AppContext } from '../src/manager/types.js'
8
10
 
@@ -10,8 +12,8 @@ const SUPERVISOR = 'master'
10
12
 
11
13
  const makeStubContext = (records: TrustedRecord[]): AppContext<AppConfig> => ({
12
14
  getConfigResource: () => ({
13
- load: async (id: string, field?: string) =>
14
- records.find(r => (field === 'name' ? r.name === id : r.id === id)) ?? null
15
+ load: async (idOrWhere: string | Criteria<TrustedRecord>) =>
16
+ firstMatch(records, typeof idOrWhere === 'string' ? { id: idOrWhere } : idOrWhere)
15
17
  })
16
18
  } as unknown as AppContext<AppConfig>)
17
19
 
@@ -61,7 +63,7 @@ describe('@owlmeans/server-auth — supervisor plugin', () => {
61
63
  const plugin = makeSupervisorPlugin(context, {
62
64
  supervisors: [SUPERVISOR],
63
65
  allowRegistration: true,
64
- resolveUser: async (userId) => ({ userId: 'internal-id', profileId: 'profile-1', entityId: 'entity-1', scopes: ['project'] })
66
+ resolveUser: async (userId) => ({ userId: 'internal-id', profileId: 'profile-1', entitySlug: 'entity-1', scopes: ['project'] })
65
67
  })
66
68
 
67
69
  const challenge = 'challenge-' + Date.now()
@@ -72,7 +74,7 @@ describe('@owlmeans/server-auth — supervisor plugin', () => {
72
74
 
73
75
  expect(credential.userId).toBe('internal-id')
74
76
  expect(credential.profileId).toBe('profile-1')
75
- expect(credential.entityId).toBe('entity-1')
77
+ expect(credential.entitySlug).toBe('entity-1')
76
78
  expect(credential.scopes).toEqual(['project'])
77
79
  })
78
80
 
package/build/.gitkeep DELETED
File without changes
@@ -1,2 +0,0 @@
1
- export declare const modules: import("@owlmeans/entrypoint").CommonEntrypoint[];
2
- //# sourceMappingURL=modules.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"modules.d.ts","sourceRoot":"","sources":["../../src/manager/modules.ts"],"names":[],"mappings":"AAkBA,eAAO,MAAM,OAAO,mDAAO,CAAA"}
@@ -1,21 +0,0 @@
1
- import { AUTHEN, AUTHEN_AUTHEN, AUTHEN_INIT, AUTHEN_RELY, MOD_RECAPTCHA } from '@owlmeans/auth';
2
- import { modules as list } from '@owlmeans/auth-common';
3
- import { modules as apiConfig } from '@owlmeans/api-config-server';
4
- import { elevate, guard } from '@owlmeans/server-entrypoint';
5
- import * as actions from './actions/index.js';
6
- import { entrypoint } from '@owlmeans/client-entrypoint';
7
- import { backend, route, RouteMethod } from '@owlmeans/route';
8
- import { handleIntermediate } from '@owlmeans/server-api';
9
- import { DEFAULT_RELY } from './consts.js';
10
- elevate(list, AUTHEN, handleIntermediate(async (_, context) => await context.updateContext()), { intermediate: true });
11
- elevate(list, AUTHEN_INIT, actions.authenticationInit);
12
- elevate(list, AUTHEN_AUTHEN, actions.authenticate);
13
- elevate(list, AUTHEN_RELY, actions.rely, guard(DEFAULT_RELY));
14
- export const modules = list;
15
- list.push(...apiConfig);
16
- list.push(entrypoint(route(MOD_RECAPTCHA, '/api/siteverify', backend({
17
- host: 'https://www.google.com',
18
- base: 'recaptcha',
19
- secure: true,
20
- }, RouteMethod.POST))));
21
- //# sourceMappingURL=modules.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"modules.js","sourceRoot":"","sources":["../../src/manager/modules.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,MAAM,EAAE,aAAa,EAAE,WAAW,EAAE,WAAW,EAAE,aAAa,EAAE,MAAM,gBAAgB,CAAA;AAC/F,OAAO,EAAE,OAAO,IAAI,IAAI,EAAE,MAAM,uBAAuB,CAAA;AACvD,OAAO,EAAE,OAAO,IAAI,SAAS,EAAE,MAAM,6BAA6B,CAAA;AAClE,OAAO,EAAE,OAAO,EAAE,KAAK,EAAE,MAAM,6BAA6B,CAAA;AAC5D,OAAO,KAAK,OAAO,MAAM,oBAAoB,CAAA;AAC7C,OAAO,EAAE,UAAU,EAAE,MAAM,6BAA6B,CAAA;AACxD,OAAO,EAAE,OAAO,EAAE,KAAK,EAAE,WAAW,EAAE,MAAM,iBAAiB,CAAA;AAC7D,OAAO,EAAE,kBAAkB,EAAE,MAAM,sBAAsB,CAAA;AACzD,OAAO,EAAE,YAAY,EAAE,MAAM,aAAa,CAAA;AAE1C,OAAO,CAAC,IAAI,EAAE,MAAM,EAAE,kBAAkB,CACtC,KAAK,EAAE,CAAC,EAAE,OAAO,EAAE,EAAE,CAAC,MAAM,OAAO,CAAC,aAAa,EAAoB,CACtE,EAAE,EAAE,YAAY,EAAE,IAAI,EAAE,CAAC,CAAA;AAC1B,OAAO,CAAC,IAAI,EAAE,WAAW,EAAE,OAAO,CAAC,kBAAkB,CAAC,CAAA;AACtD,OAAO,CAAC,IAAI,EAAE,aAAa,EAAE,OAAO,CAAC,YAAY,CAAC,CAAA;AAClD,OAAO,CAAC,IAAI,EAAE,WAAW,EAAE,OAAO,CAAC,IAAI,EAAE,KAAK,CAAC,YAAY,CAAC,CAAC,CAAA;AAE7D,MAAM,CAAC,MAAM,OAAO,GAAG,IAAI,CAAA;AAC3B,IAAI,CAAC,IAAI,CAAC,GAAG,SAAS,CAAC,CAAA;AACvB,IAAI,CAAC,IAAI,CACP,UAAU,CACR,KAAK,CAAC,aAAa,EAAE,iBAAiB,EAAE,OAAO,CAAC;IAC9C,IAAI,EAAE,wBAAwB;IAC9B,IAAI,EAAE,WAAW;IACjB,MAAM,EAAE,IAAI;CACb,EAAE,WAAW,CAAC,IAAI,CAAC,CAAC,CACtB,CACF,CAAA"}
@@ -1,3 +0,0 @@
1
- import type { ServerEntrypoint } from '@owlmeans/server-entrypoint';
2
- export declare const modules: ServerEntrypoint<unknown>[];
3
- //# sourceMappingURL=modules.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"modules.d.ts","sourceRoot":"","sources":["../src/modules.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,6BAA6B,CAAA;AAOnE,eAAO,MAAM,OAAO,EAAE,gBAAgB,CAAC,OAAO,CAAC,EAK9C,CAAA"}
package/build/modules.js DELETED
@@ -1,11 +0,0 @@
1
- import { elevate } from '@owlmeans/server-entrypoint';
2
- import { modules as list } from '@owlmeans/auth-common';
3
- import { DISPATCHER, DISPATCHER_AUTHEN } from '@owlmeans/auth';
4
- import { authenticate } from './actions/service.js';
5
- import { stab, elevate as celevate } from '@owlmeans/client-entrypoint';
6
- elevate(list, DISPATCHER_AUTHEN, authenticate);
7
- celevate(list, DISPATCHER, stab);
8
- export const modules = [
9
- ...list.filter((module) => [DISPATCHER, DISPATCHER_AUTHEN].includes(module.getAlias()))
10
- ];
11
- //# sourceMappingURL=modules.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"modules.js","sourceRoot":"","sources":["../src/modules.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,OAAO,EAAE,MAAM,6BAA6B,CAAA;AACrD,OAAO,EAAE,OAAO,IAAI,IAAI,EAAE,MAAM,uBAAuB,CAAA;AACvD,OAAO,EAAE,UAAU,EAAE,iBAAiB,EAAE,MAAM,gBAAgB,CAAA;AAE9D,OAAO,EAAE,YAAY,EAAE,MAAM,sBAAsB,CAAA;AACnD,OAAO,EAAE,IAAI,EAAE,OAAO,IAAI,QAAQ,EAAE,MAAM,6BAA6B,CAAA;AAEvE,OAAO,CAAC,IAAI,EAAE,iBAAiB,EAAE,YAAY,CAAC,CAAA;AAC9C,QAAQ,CAAC,IAAI,EAAE,UAAU,EAAE,IAAI,CAAC,CAAA;AAEhC,MAAM,CAAC,MAAM,OAAO,GAAgC;IAClD,GAAG,IAAI,CAAC,MAAM,CACZ,CAAC,MAAM,EAAuC,EAAE,CAC9C,CAAC,UAAU,EAAE,iBAAiB,CAAC,CAAC,QAAQ,CAAC,MAAM,CAAC,QAAQ,EAAE,CAAC,CAC9D;CACF,CAAA"}
@@ -1,29 +0,0 @@
1
-
2
- import { AUTHEN, AUTHEN_AUTHEN, AUTHEN_INIT, AUTHEN_RELY, MOD_RECAPTCHA } from '@owlmeans/auth'
3
- import { modules as list } from '@owlmeans/auth-common'
4
- import { modules as apiConfig } from '@owlmeans/api-config-server'
5
- import { elevate, guard } from '@owlmeans/server-entrypoint'
6
- import * as actions from './actions/index.js'
7
- import { entrypoint } from '@owlmeans/client-entrypoint'
8
- import { backend, route, RouteMethod } from '@owlmeans/route'
9
- import { handleIntermediate } from '@owlmeans/server-api'
10
- import { DEFAULT_RELY } from './consts.js'
11
-
12
- elevate(list, AUTHEN, handleIntermediate(
13
- async (_, context) => await context.updateContext() as typeof context
14
- ), { intermediate: true })
15
- elevate(list, AUTHEN_INIT, actions.authenticationInit)
16
- elevate(list, AUTHEN_AUTHEN, actions.authenticate)
17
- elevate(list, AUTHEN_RELY, actions.rely, guard(DEFAULT_RELY))
18
-
19
- export const modules = list
20
- list.push(...apiConfig)
21
- list.push(
22
- entrypoint(
23
- route(MOD_RECAPTCHA, '/api/siteverify', backend({
24
- host: 'https://www.google.com',
25
- base: 'recaptcha',
26
- secure: true,
27
- }, RouteMethod.POST))
28
- )
29
- )
package/src/modules.ts DELETED
@@ -1,17 +0,0 @@
1
-
2
- import { elevate } from '@owlmeans/server-entrypoint'
3
- import { modules as list } from '@owlmeans/auth-common'
4
- import { DISPATCHER, DISPATCHER_AUTHEN } from '@owlmeans/auth'
5
- import type { ServerEntrypoint } from '@owlmeans/server-entrypoint'
6
- import { authenticate } from './actions/service.js'
7
- import { stab, elevate as celevate } from '@owlmeans/client-entrypoint'
8
-
9
- elevate(list, DISPATCHER_AUTHEN, authenticate)
10
- celevate(list, DISPATCHER, stab)
11
-
12
- export const modules: ServerEntrypoint<unknown>[] = [
13
- ...list.filter(
14
- (module): module is ServerEntrypoint<unknown> =>
15
- [DISPATCHER, DISPATCHER_AUTHEN].includes(module.getAlias())
16
- )
17
- ]