@backstage/plugin-auth-backend 0.25.3 → 0.25.4-next.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.
- package/CHANGELOG.md +19 -0
- package/dist/authPlugin.cjs.js +4 -1
- package/dist/authPlugin.cjs.js.map +1 -1
- package/dist/database/OidcDatabase.cjs.js +214 -0
- package/dist/database/OidcDatabase.cjs.js.map +1 -0
- package/dist/service/OidcRouter.cjs.js +284 -5
- package/dist/service/OidcRouter.cjs.js.map +1 -1
- package/dist/service/OidcService.cjs.js +250 -5
- package/dist/service/OidcService.cjs.js.map +1 -1
- package/dist/service/router.cjs.js +10 -2
- package/dist/service/router.cjs.js.map +1 -1
- package/migrations/20250909120000_oidc_client_registration.js +159 -0
- package/package.json +15 -13
|
@@ -0,0 +1,159 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* Copyright 2025 The Backstage Authors
|
|
3
|
+
*
|
|
4
|
+
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
5
|
+
* you may not use this file except in compliance with the License.
|
|
6
|
+
* You may obtain a copy of the License at
|
|
7
|
+
*
|
|
8
|
+
* http://www.apache.org/licenses/LICENSE-2.0
|
|
9
|
+
*
|
|
10
|
+
* Unless required by applicable law or agreed to in writing, software
|
|
11
|
+
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
12
|
+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
13
|
+
* See the License for the specific language governing permissions and
|
|
14
|
+
* limitations under the License.
|
|
15
|
+
*/
|
|
16
|
+
|
|
17
|
+
// @ts-check
|
|
18
|
+
|
|
19
|
+
/**
|
|
20
|
+
* @param {import('knex').Knex} knex
|
|
21
|
+
*/
|
|
22
|
+
exports.up = async function up(knex) {
|
|
23
|
+
// These tables make up the OIDC client registration flow.
|
|
24
|
+
// Clients are the top of the tree, that are created by the client registration flow.
|
|
25
|
+
await knex.schema.createTable('oidc_clients', table => {
|
|
26
|
+
table.comment(
|
|
27
|
+
'OIDC clients that are registered via dynamic client registration',
|
|
28
|
+
);
|
|
29
|
+
|
|
30
|
+
table
|
|
31
|
+
.string('client_id')
|
|
32
|
+
.primary()
|
|
33
|
+
.notNullable()
|
|
34
|
+
.comment('The unique client ID of the client');
|
|
35
|
+
|
|
36
|
+
table
|
|
37
|
+
.string('client_secret')
|
|
38
|
+
.notNullable()
|
|
39
|
+
.comment('The client secret of the client');
|
|
40
|
+
|
|
41
|
+
table
|
|
42
|
+
.string('client_name')
|
|
43
|
+
.notNullable()
|
|
44
|
+
.comment('The name of the client, should be human readable');
|
|
45
|
+
|
|
46
|
+
table
|
|
47
|
+
.text('response_types', 'longtext')
|
|
48
|
+
.notNullable()
|
|
49
|
+
.comment('JSON array of supported response types');
|
|
50
|
+
|
|
51
|
+
table
|
|
52
|
+
.text('grant_types', 'longtext')
|
|
53
|
+
.notNullable()
|
|
54
|
+
.comment('JSON array of supported grant types');
|
|
55
|
+
|
|
56
|
+
table
|
|
57
|
+
.text('redirect_uris', 'longtext')
|
|
58
|
+
.notNullable()
|
|
59
|
+
.comment('Allowed redirect URIs as JSON array');
|
|
60
|
+
|
|
61
|
+
table.text('scope').nullable().comment('Default scopes for the client');
|
|
62
|
+
|
|
63
|
+
table
|
|
64
|
+
.text('metadata', 'longtext')
|
|
65
|
+
.nullable()
|
|
66
|
+
.comment('Additional client metadata as JSON');
|
|
67
|
+
});
|
|
68
|
+
|
|
69
|
+
await knex.schema.createTable('oauth_authorization_sessions', table => {
|
|
70
|
+
table.comment('Core OAuth authorization sessions with shared context');
|
|
71
|
+
|
|
72
|
+
table
|
|
73
|
+
.string('id')
|
|
74
|
+
.primary()
|
|
75
|
+
.notNullable()
|
|
76
|
+
.comment('Unique session identifier');
|
|
77
|
+
|
|
78
|
+
table.string('client_id').notNullable().comment('OIDC client identifier');
|
|
79
|
+
|
|
80
|
+
table
|
|
81
|
+
.string('user_entity_ref')
|
|
82
|
+
.nullable()
|
|
83
|
+
.comment('Backstage user entity reference');
|
|
84
|
+
|
|
85
|
+
table
|
|
86
|
+
.text('redirect_uri', 'longtext')
|
|
87
|
+
.notNullable()
|
|
88
|
+
.comment('Client redirect URI');
|
|
89
|
+
|
|
90
|
+
table.text('scope').nullable().comment('Requested scopes space-separated');
|
|
91
|
+
|
|
92
|
+
table.string('state').nullable().comment('Client state parameter');
|
|
93
|
+
|
|
94
|
+
table.string('response_type').notNullable().comment('OAuth2 response type');
|
|
95
|
+
|
|
96
|
+
table.string('code_challenge').nullable().comment('PKCE code challenge');
|
|
97
|
+
|
|
98
|
+
table
|
|
99
|
+
.string('code_challenge_method')
|
|
100
|
+
.nullable()
|
|
101
|
+
.comment('PKCE code challenge method');
|
|
102
|
+
|
|
103
|
+
table.string('nonce').nullable().comment('OIDC nonce parameter');
|
|
104
|
+
|
|
105
|
+
table
|
|
106
|
+
.enum('status', ['pending', 'approved', 'rejected', 'expired'])
|
|
107
|
+
.defaultTo('pending')
|
|
108
|
+
.comment('Authorization session status');
|
|
109
|
+
|
|
110
|
+
table
|
|
111
|
+
.timestamp('expires_at', { useTz: true, precision: 0 })
|
|
112
|
+
.notNullable()
|
|
113
|
+
.comment('Session expiration timestamp');
|
|
114
|
+
|
|
115
|
+
table.foreign('client_id').references('client_id').inTable('oidc_clients');
|
|
116
|
+
table.index(['client_id', 'user_entity_ref']);
|
|
117
|
+
table.index(['status', 'expires_at']);
|
|
118
|
+
});
|
|
119
|
+
|
|
120
|
+
await knex.schema.createTable('oidc_authorization_codes', table => {
|
|
121
|
+
table.comment('OAuth authorization codes for code exchange flow');
|
|
122
|
+
|
|
123
|
+
table
|
|
124
|
+
.string('code')
|
|
125
|
+
.primary()
|
|
126
|
+
.notNullable()
|
|
127
|
+
.comment('Unique authorization code');
|
|
128
|
+
|
|
129
|
+
table
|
|
130
|
+
.string('session_id')
|
|
131
|
+
.notNullable()
|
|
132
|
+
.comment('Authorization session identifier');
|
|
133
|
+
|
|
134
|
+
table
|
|
135
|
+
.timestamp('expires_at', { useTz: true, precision: 0 })
|
|
136
|
+
.notNullable()
|
|
137
|
+
.comment('Authorization code expiration timestamp');
|
|
138
|
+
|
|
139
|
+
table
|
|
140
|
+
.boolean('used')
|
|
141
|
+
.defaultTo(false)
|
|
142
|
+
.comment('Whether the authorization code has been used');
|
|
143
|
+
|
|
144
|
+
table
|
|
145
|
+
.foreign('session_id')
|
|
146
|
+
.references('id')
|
|
147
|
+
.inTable('oauth_authorization_sessions')
|
|
148
|
+
.onDelete('CASCADE');
|
|
149
|
+
});
|
|
150
|
+
};
|
|
151
|
+
|
|
152
|
+
/**
|
|
153
|
+
* @param {import('knex').Knex} knex
|
|
154
|
+
*/
|
|
155
|
+
exports.down = async function down(knex) {
|
|
156
|
+
await knex.schema.dropTable('oidc_authorization_codes');
|
|
157
|
+
await knex.schema.dropTable('oauth_authorization_sessions');
|
|
158
|
+
await knex.schema.dropTable('oidc_clients');
|
|
159
|
+
};
|
package/package.json
CHANGED
|
@@ -1,11 +1,12 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@backstage/plugin-auth-backend",
|
|
3
|
-
"version": "0.25.
|
|
3
|
+
"version": "0.25.4-next.1",
|
|
4
4
|
"description": "A Backstage backend plugin that handles authentication",
|
|
5
5
|
"backstage": {
|
|
6
6
|
"role": "backend-plugin",
|
|
7
7
|
"pluginId": "auth",
|
|
8
8
|
"pluginPackages": [
|
|
9
|
+
"@backstage/plugin-auth",
|
|
9
10
|
"@backstage/plugin-auth-backend",
|
|
10
11
|
"@backstage/plugin-auth-node",
|
|
11
12
|
"@backstage/plugin-auth-react"
|
|
@@ -46,13 +47,13 @@
|
|
|
46
47
|
"test": "backstage-cli package test"
|
|
47
48
|
},
|
|
48
49
|
"dependencies": {
|
|
49
|
-
"@backstage/backend-plugin-api": "
|
|
50
|
-
"@backstage/catalog-model": "
|
|
51
|
-
"@backstage/config": "
|
|
52
|
-
"@backstage/errors": "
|
|
53
|
-
"@backstage/plugin-auth-node": "
|
|
54
|
-
"@backstage/plugin-catalog-node": "
|
|
55
|
-
"@backstage/types": "
|
|
50
|
+
"@backstage/backend-plugin-api": "1.4.3-next.0",
|
|
51
|
+
"@backstage/catalog-model": "1.7.5",
|
|
52
|
+
"@backstage/config": "1.3.3",
|
|
53
|
+
"@backstage/errors": "1.2.7",
|
|
54
|
+
"@backstage/plugin-auth-node": "0.6.7-next.1",
|
|
55
|
+
"@backstage/plugin-catalog-node": "1.19.0-next.1",
|
|
56
|
+
"@backstage/types": "1.2.1",
|
|
56
57
|
"@google-cloud/firestore": "^7.0.0",
|
|
57
58
|
"connect-session-knex": "^4.0.0",
|
|
58
59
|
"cookie-parser": "^1.4.5",
|
|
@@ -63,16 +64,17 @@
|
|
|
63
64
|
"knex": "^3.0.0",
|
|
64
65
|
"lodash": "^4.17.21",
|
|
65
66
|
"luxon": "^3.0.0",
|
|
67
|
+
"matcher": "^4.0.0",
|
|
66
68
|
"minimatch": "^9.0.0",
|
|
67
69
|
"passport": "^0.7.0",
|
|
68
70
|
"uuid": "^11.0.0"
|
|
69
71
|
},
|
|
70
72
|
"devDependencies": {
|
|
71
|
-
"@backstage/backend-defaults": "
|
|
72
|
-
"@backstage/backend-test-utils": "
|
|
73
|
-
"@backstage/cli": "
|
|
74
|
-
"@backstage/plugin-auth-backend-module-google-provider": "
|
|
75
|
-
"@backstage/plugin-auth-backend-module-guest-provider": "
|
|
73
|
+
"@backstage/backend-defaults": "0.12.1-next.1",
|
|
74
|
+
"@backstage/backend-test-utils": "1.9.0-next.1",
|
|
75
|
+
"@backstage/cli": "0.34.2-next.2",
|
|
76
|
+
"@backstage/plugin-auth-backend-module-google-provider": "0.3.7-next.0",
|
|
77
|
+
"@backstage/plugin-auth-backend-module-guest-provider": "0.2.12-next.0",
|
|
76
78
|
"@types/cookie-parser": "^1.4.2",
|
|
77
79
|
"@types/express": "^4.17.6",
|
|
78
80
|
"@types/express-session": "^1.17.2",
|