@1auth/authn 0.0.0-alpha.3 → 0.0.0-alpha.30

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 (2) hide show
  1. package/index.js +39 -19
  2. package/package.json +3 -3
package/index.js CHANGED
@@ -4,12 +4,15 @@ import { randomId, makeSymetricKey } from '@1auth/crypto'
4
4
  export const options = {
5
5
  store: undefined,
6
6
  notify: undefined,
7
- table: 'credentials',
7
+ table: 'authentications',
8
+ idGenerate: true,
9
+ idPrefix: 'authn',
10
+ randomId: undefined,
8
11
  authenticationDuration: 500, // min duration authentication should take (ms)
9
12
  usernameExists: [] // hooks to allow what to be used as a username
10
13
  }
11
14
  export default (params) => {
12
- Object.assign(options, params)
15
+ Object.assign(options, { randomId }, params)
13
16
  }
14
17
  export const getOptions = () => options
15
18
 
@@ -19,7 +22,6 @@ export const create = async (
19
22
  parentOptions
20
23
  ) => {
21
24
  const now = nowInSeconds()
22
- id ??= await randomId.create()
23
25
  const type = parentOptions.id + '-' + parentOptions[credentialType].type
24
26
  const otp = parentOptions[credentialType].otp
25
27
  const expire = parentOptions[credentialType].expire
@@ -32,10 +34,9 @@ export const create = async (
32
34
  encryptedKey,
33
35
  sub
34
36
  )
35
- return parentOptions.store.insert(options.table, {
37
+ const params = {
36
38
  expire,
37
39
  ...rest,
38
- id,
39
40
  sub,
40
41
  type,
41
42
  otp,
@@ -43,7 +44,13 @@ export const create = async (
43
44
  value: encryptedData,
44
45
  create: now,
45
46
  update: now
46
- })
47
+ }
48
+ if (options.idGenerate) {
49
+ id ??= await options.randomId.create(options.idPrefix)
50
+ params.id = id
51
+ }
52
+ const { id: serialId } = await options.store.insert(options.table, params)
53
+ return serialId
47
54
  }
48
55
 
49
56
  export const update = async (
@@ -57,7 +64,7 @@ export const update = async (
57
64
  encryptionKey,
58
65
  sub
59
66
  )
60
- return parentOptions.store.update(
67
+ return options.store.update(
61
68
  options.table,
62
69
  { id, sub },
63
70
  {
@@ -77,17 +84,19 @@ export const subject = async (username) => {
77
84
  }
78
85
 
79
86
  export const authenticate = async (username, secret, parentOptions) => {
80
- const timeout = setTimeout(() => {}, options.authenticationDuration)
87
+ const timeout = setTimeout(options.authenticationDuration)
81
88
  const type = parentOptions.id + '-' + parentOptions.secret.type
82
89
 
83
90
  const sub = await subject(username)
84
91
 
85
- const credentials = await parentOptions.store.selectList(options.table, {
92
+ const credentials = await options.store.selectList(options.table, {
86
93
  sub,
87
94
  type
88
- }) // TODO and verify is not null
95
+ })
89
96
  let valid, id, encryptionKey
90
97
  for (const credential of credentials) {
98
+ // non-opt credentials must be verified before use
99
+ if (!credential.otp && !credential.verify) continue
91
100
  let { value, encryptionKey: encryptedKey, ...rest } = credential
92
101
  value = await parentOptions.secret.decode(value, encryptedKey, sub)
93
102
  valid = await parentOptions.secret.verify(secret, value, rest)
@@ -98,9 +107,19 @@ export const authenticate = async (username, secret, parentOptions) => {
98
107
  }
99
108
  }
100
109
 
101
- if (valid && parentOptions.secret.otp) {
102
- await parentOptions.store.remove(options.table, { id, sub })
110
+ if (parentOptions.secret.otp) {
111
+ // delete OTP to prevent re-use
112
+ await options.store.remove(options.table, { id, sub })
113
+ } else if (valid && parentOptions.id !== 'WebAuthn') {
114
+ // WebAuthn has to update, skip here
115
+ const now = nowInSeconds()
116
+ await options.store.update(
117
+ options.table,
118
+ { id, sub },
119
+ { update: now, lastused: now }
120
+ )
103
121
  }
122
+
104
123
  await timeout
105
124
  if (!valid) throw new Error('401 Unauthorized')
106
125
  return { sub, id, encryptionKey, ...valid }
@@ -108,18 +127,19 @@ export const authenticate = async (username, secret, parentOptions) => {
108
127
 
109
128
  export const verifySecret = async (sub, id, parentOptions) => {
110
129
  // const type = parentOptions.id + '-' + parentOptions.secret.type
111
- await parentOptions.store.update(
130
+ const now = nowInSeconds()
131
+ await options.store.update(
112
132
  options.table,
113
133
  { id, sub },
114
- { verify: nowInSeconds() }
134
+ { update: now, verify: now }
115
135
  )
116
136
  }
117
137
 
118
138
  export const verify = async (credentialType, sub, token, parentOptions) => {
119
- const timeout = setTimeout(() => {}, options.authenticationDuration)
139
+ const timeout = setTimeout(options.authenticationDuration)
120
140
  const type = parentOptions.id + '-' + parentOptions[credentialType].type
121
141
  let id
122
- const credentials = await parentOptions.store.selectList(options.table, {
142
+ const credentials = await options.store.selectList(options.table, {
123
143
  sub,
124
144
  type
125
145
  })
@@ -129,7 +149,7 @@ export const verify = async (credentialType, sub, token, parentOptions) => {
129
149
  // return rows
130
150
  // }
131
151
  //
132
- // return parentOptions.store.select(options.table, { id: sub, type })
152
+ // return options.store.select(options.table, { id: sub, type })
133
153
  // })
134
154
 
135
155
  let valid
@@ -147,7 +167,7 @@ export const verify = async (credentialType, sub, token, parentOptions) => {
147
167
  }
148
168
  }
149
169
  if (valid && parentOptions[credentialType].otp) {
150
- await parentOptions.store.remove(options.table, { id, sub })
170
+ await options.store.remove(options.table, { id, sub })
151
171
  }
152
172
  if (!valid) throw new Error('401 Unauthorized')
153
173
  await timeout
@@ -155,7 +175,7 @@ export const verify = async (credentialType, sub, token, parentOptions) => {
155
175
  }
156
176
 
157
177
  export const expire = async (sub, id, parentOptions = options) => {
158
- await parentOptions.store.remove(options.table, { id, sub })
178
+ await options.store.remove(options.table, { id, sub })
159
179
  }
160
180
 
161
181
  // TODO manage onboard state
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@1auth/authn",
3
- "version": "0.0.0-alpha.3",
3
+ "version": "0.0.0-alpha.30",
4
4
  "description": "",
5
5
  "type": "module",
6
6
  "engines": {
@@ -48,8 +48,8 @@
48
48
  "url": "https://github.com/willfarrell/1auth/issues"
49
49
  },
50
50
  "homepage": "https://github.com/willfarrell/1auth",
51
- "gitHead": "a02b1e01f039718f213d79b91d04ed660a955c73",
51
+ "gitHead": "bba2971096bfd6bcc30e7613fae272896456ecfa",
52
52
  "dependencies": {
53
- "@1auth/crypto": "0.0.0-alpha.3"
53
+ "@1auth/crypto": "0.0.0-alpha.30"
54
54
  }
55
55
  }